Merge pull request #363 from gyuho/etcd-3.3-rc

*: refactor for etcd v3.3 tests, drop old Consul, Zookeeper versions
This commit is contained in:
Gyuho Lee 2018-01-09 13:01:50 -08:00 committed by GitHub
commit 68dcc5dc70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
983 changed files with 346993 additions and 68894 deletions

23
.gitignore vendored
View File

@ -1,2 +1,23 @@
/.DS_Store # See http://help.github.com/ignore-files/ for more about ignoring files.
# IDEs and editors
/.idea
/.vscode /.vscode
#System Files
.DS_Store
# Ignore everything in vendor/, except for *.go files,
# LICENSE and COPYING. Ignore Go tests.
# https://github.com/golang/dep/issues/120#issuecomment-306518546
vendor/**/*
!vendor/**/
!vendor/**/*.go
!vendor/**/*.c
!vendor/**/*.cpp
!vendor/**/*.s
!vendor/**/COPYING*
!vendor/**/PATENTS*
!vendor/**/NOTICE*
!vendor/**/LICENSE*
vendor/**/*_test.go

View File

@ -3,7 +3,7 @@ language: go
sudo: false sudo: false
go: go:
- 1.8 - 1.9.2
script: script:
- ./scripts/tests.sh - ./scripts/tests.sh

400
Gopkg.lock generated Normal file
View File

@ -0,0 +1,400 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "default"
name = "bitbucket.org/zombiezen/gopdf"
packages = ["pdf"]
revision = "1c63dc69751bc45441c2ce1f56b631c55294b4d5"
[[projects]]
name = "cloud.google.com/go"
packages = [
"compute/metadata",
"iam",
"internal",
"internal/optional",
"internal/version",
"storage"
]
revision = "2a6493c7a9214bf56c1003bd97443d505cc7e952"
source = "https://github.com/GoogleCloudPlatform/google-cloud-go"
[[projects]]
branch = "master"
name = "github.com/ajstarks/svgo"
packages = ["."]
revision = "f9be02f22f2c23fbdd01ed76e5c7f5af79e13f9b"
[[projects]]
name = "github.com/cheggaaa/pb"
packages = ["."]
revision = "18d384da9bdc1e5a08fc2a62a494c321d9ae74ea"
source = "https://github.com/cheggaaa/pb"
[[projects]]
name = "github.com/coreos/etcd"
packages = [
"auth/authpb",
"clientv3",
"etcdserver/api/v3rpc/rpctypes",
"etcdserver/etcdserverpb",
"mvcc/mvccpb",
"pkg/cpuutil",
"pkg/netutil",
"pkg/report",
"pkg/types"
]
revision = "2dfabfbef6ae5ac3553c7a14ee757ebccbeef538"
source = "https://github.com/coreos/etcd"
[[projects]]
name = "github.com/coreos/go-systemd"
packages = ["journal"]
revision = "d2196463941895ee908e13531a23a39feb9e1243"
version = "v15"
[[projects]]
name = "github.com/coreos/pkg"
packages = ["capnslog"]
revision = "97fdf19511ea361ae1c100dd393cc47f8dcfa1e1"
source = "https://github.com/coreos/pkg"
[[projects]]
name = "github.com/dustin/go-humanize"
packages = ["."]
revision = "bb3d318650d48840a39aa21a027c6630e198e626"
source = "https://github.com/dustin/go-humanize"
[[projects]]
name = "github.com/gogo/protobuf"
packages = [
"gogoproto",
"proto",
"protoc-gen-gogo/descriptor"
]
revision = "160de10b2537169b5ae3e7e221d28269ef40d311"
source = "https://github.com/gogo/protobuf"
[[projects]]
branch = "master"
name = "github.com/golang/freetype"
packages = [
".",
"raster",
"truetype"
]
revision = "e2365dfdc4a05e4b8299a783240d4a7d5a65d4e4"
[[projects]]
name = "github.com/golang/protobuf"
packages = [
"proto",
"protoc-gen-go/descriptor",
"ptypes",
"ptypes/any",
"ptypes/duration",
"ptypes/timestamp"
]
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
source = "https://github.com/golang/protobuf"
[[projects]]
name = "github.com/googleapis/gax-go"
packages = ["."]
revision = "317e0006254c44a0ac427cc52a0e083ff0b9622f"
version = "v2.0.0"
[[projects]]
name = "github.com/gyuho/dataframe"
packages = ["."]
revision = "008fc241adc41d4bd5c54b9f6564ef16407c030e"
source = "https://github.com/gyuho/dataframe"
[[projects]]
name = "github.com/gyuho/linux-inspect"
packages = [
"df",
"inspect",
"pkg/fileutil",
"pkg/timeutil",
"proc",
"schema",
"top"
]
revision = "187ae4baf4c1bed94dfeb338dfc1137cd6dfadc3"
source = "https://github.com/gyuho/linux-inspect"
[[projects]]
name = "github.com/hashicorp/consul"
packages = ["api"]
revision = "b55059fc3d0327c92c41431e57dfd2df3f956b03"
source = "https://github.com/hashicorp/consul"
[[projects]]
branch = "master"
name = "github.com/hashicorp/go-cleanhttp"
packages = ["."]
revision = "d5fe4b57a186c716b0e00b8c301cbd9b4182694d"
[[projects]]
branch = "master"
name = "github.com/hashicorp/go-rootcerts"
packages = ["."]
revision = "6bb64b370b90e7ef1fa532be9e591a81c3493e00"
[[projects]]
name = "github.com/hashicorp/serf"
packages = ["coordinate"]
revision = "d6574a5bb1226678d7010325fb6c985db20ee458"
version = "v0.8.1"
[[projects]]
name = "github.com/inconshreveable/mousetrap"
packages = ["."]
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
version = "v1.0"
[[projects]]
name = "github.com/kr/pty"
packages = ["."]
revision = "1278f20d9cf7455f0465f3bf74a73d1eeb555c0f"
source = "https://github.com/kr/pty"
[[projects]]
branch = "master"
name = "github.com/llgcode/draw2d"
packages = [
".",
"draw2dbase",
"draw2dimg"
]
revision = "50aafedab485a360a03c4763631448285d324125"
[[projects]]
name = "github.com/mattn/go-runewidth"
packages = ["."]
revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
version = "v0.0.2"
[[projects]]
branch = "master"
name = "github.com/mitchellh/go-homedir"
packages = ["."]
revision = "b8bc1bf767474819792c23f32d8286a45736f1c6"
[[projects]]
name = "github.com/olekukonko/tablewriter"
packages = ["."]
revision = "96aac992fc8b1a4c83841a6c3e7178d20d989625"
source = "https://github.com/olekukonko/tablewriter"
[[projects]]
name = "github.com/samuel/go-zookeeper"
packages = ["zk"]
revision = "471cd4e61d7a78ece1791fa5faa0345dc8c7d5a5"
source = "https://github.com/samuel/go-zookeeper"
[[projects]]
name = "github.com/spf13/cobra"
packages = ["."]
revision = "b95ab734e27d33e0d8fbabf71ca990568d4e2020"
source = "https://github.com/spf13/cobra"
[[projects]]
name = "github.com/spf13/pflag"
packages = ["."]
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
version = "v1.0.0"
[[projects]]
branch = "master"
name = "golang.org/x/image"
packages = [
"draw",
"font",
"math/f64",
"math/fixed",
"tiff",
"tiff/lzw"
]
revision = "12117c17ca67ffa1ce22e9409f3b0b0a93ac08c7"
[[projects]]
name = "golang.org/x/net"
packages = [
"context",
"context/ctxhttp",
"http2",
"http2/hpack",
"idna",
"internal/timeseries",
"lex/httplex",
"trace"
]
revision = "434ec0c7fe3742c984919a691b2018a6e9694425"
source = "https://github.com/golang/net"
[[projects]]
name = "golang.org/x/oauth2"
packages = [
".",
"google",
"internal",
"jws",
"jwt"
]
revision = "30785a2c434e431ef7c507b54617d6a951d5f2b4"
source = "https://github.com/golang/oauth2"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix"]
revision = "d38bf781f16e180a1b2ad82697d2f81d7b7ecfac"
[[projects]]
branch = "master"
name = "golang.org/x/text"
packages = [
"collate",
"collate/build",
"internal/colltab",
"internal/gen",
"internal/tag",
"internal/triegen",
"internal/ucd",
"language",
"secure/bidirule",
"transform",
"unicode/bidi",
"unicode/cldr",
"unicode/norm",
"unicode/rangetable"
]
revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3"
[[projects]]
name = "golang.org/x/time"
packages = ["rate"]
revision = "6dc17368e09b0e8634d71cac8168d853e869a0c7"
source = "https://github.com/golang/time"
[[projects]]
branch = "master"
name = "gonum.org/v1/gonum"
packages = [
"blas",
"blas/blas64",
"blas/gonum",
"floats",
"internal/asm/c128",
"internal/asm/f32",
"internal/asm/f64",
"internal/math32",
"lapack",
"lapack/gonum",
"lapack/lapack64",
"mat"
]
revision = "69fc04c7c31754cf196d3bcc70c3bc0eec9da1b7"
[[projects]]
name = "gonum.org/v1/plot"
packages = [
".",
"palette",
"plotter",
"plotutil",
"tools/bezier",
"vg",
"vg/draw",
"vg/fonts",
"vg/vgeps",
"vg/vgimg",
"vg/vgpdf",
"vg/vgsvg"
]
revision = "feab214a240f4312b98ab52baf662b55ff1ee377"
source = "https://github.com/gonum/plot"
[[projects]]
name = "google.golang.org/api"
packages = [
"gensupport",
"googleapi",
"googleapi/internal/uritemplates",
"googleapi/transport",
"internal",
"iterator",
"option",
"storage/v1",
"transport/http"
]
revision = "e5c227fa33ebccc5a430d863efae400431fc0e85"
source = "https://github.com/google/google-api-go-client"
[[projects]]
name = "google.golang.org/appengine"
packages = [
".",
"internal",
"internal/app_identity",
"internal/base",
"internal/datastore",
"internal/log",
"internal/modules",
"internal/remote_api",
"internal/urlfetch",
"urlfetch"
]
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
version = "v1.0.0"
[[projects]]
branch = "master"
name = "google.golang.org/genproto"
packages = [
"googleapis/api/annotations",
"googleapis/iam/v1",
"googleapis/rpc/status"
]
revision = "a8101f21cf983e773d0c1133ebc5424792003214"
[[projects]]
name = "google.golang.org/grpc"
packages = [
".",
"balancer",
"codes",
"connectivity",
"credentials",
"grpclb/grpc_lb_v1/messages",
"grpclog",
"health/grpc_health_v1",
"internal",
"keepalive",
"metadata",
"naming",
"peer",
"resolver",
"stats",
"status",
"tap",
"transport"
]
revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e"
source = "https://github.com/grpc/grpc-go"
[[projects]]
name = "gopkg.in/yaml.v2"
packages = ["."]
revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4"
source = "https://github.com/go-yaml/yaml"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "21abf25cf507cffab0266c5836fb8acc3cb14f96b0f3fba49e0c55b85fedf5e5"
solver-name = "gps-cdcl"
solver-version = 1

143
Gopkg.toml Normal file
View File

@ -0,0 +1,143 @@
################################
# Direct dependencies
# v3.3.0 RC
[[constraint]]
name = "github.com/coreos/etcd"
source = "https://github.com/coreos/etcd"
revision = "2dfabfbef6ae5ac3553c7a14ee757ebccbeef538"
# v1.7.5
[[constraint]]
name = "google.golang.org/grpc"
source = "https://github.com/grpc/grpc-go"
revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e"
[[constraint]]
name = "github.com/gogo/protobuf"
source = "https://github.com/gogo/protobuf"
revision = "160de10b2537169b5ae3e7e221d28269ef40d311"
[[constraint]]
name = "github.com/golang/protobuf"
source = "https://github.com/golang/protobuf"
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
[[constraint]]
name = "golang.org/x/net"
source = "https://github.com/golang/net"
revision = "434ec0c7fe3742c984919a691b2018a6e9694425"
[[constraint]]
name = "golang.org/x/time"
source = "https://github.com/golang/time"
revision = "6dc17368e09b0e8634d71cac8168d853e869a0c7"
[[constraint]]
name = "gopkg.in/yaml.v2"
source = "https://github.com/go-yaml/yaml"
revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4"
[[constraint]]
name = "github.com/dustin/go-humanize"
source = "https://github.com/dustin/go-humanize"
revision = "bb3d318650d48840a39aa21a027c6630e198e626"
[[constraint]]
name = "github.com/spf13/cobra"
source = "https://github.com/spf13/cobra"
revision = "b95ab734e27d33e0d8fbabf71ca990568d4e2020"
[[constraint]]
name = "github.com/olekukonko/tablewriter"
source = "https://github.com/olekukonko/tablewriter"
revision = "96aac992fc8b1a4c83841a6c3e7178d20d989625"
[[constraint]]
name = "github.com/cheggaaa/pb"
source = "https://github.com/cheggaaa/pb"
revision = "18d384da9bdc1e5a08fc2a62a494c321d9ae74ea"
[[constraint]]
name = "github.com/samuel/go-zookeeper"
source = "https://github.com/samuel/go-zookeeper"
revision = "471cd4e61d7a78ece1791fa5faa0345dc8c7d5a5"
[[constraint]]
name = "github.com/hashicorp/consul"
source = "https://github.com/hashicorp/consul"
revision = "b55059fc3d0327c92c41431e57dfd2df3f956b03"
[[constraint]]
name = "github.com/gyuho/dataframe"
source = "https://github.com/gyuho/dataframe"
revision = "008fc241adc41d4bd5c54b9f6564ef16407c030e"
[[constraint]]
name = "github.com/gyuho/linux-inspect"
source = "https://github.com/gyuho/linux-inspect"
revision = "187ae4baf4c1bed94dfeb338dfc1137cd6dfadc3"
[[constraint]]
name = "gonum.org/v1/plot"
source = "https://github.com/gonum/plot"
revision = "feab214a240f4312b98ab52baf662b55ff1ee377"
[[constraint]]
name = "github.com/coreos/pkg"
source = "https://github.com/coreos/pkg"
revision = "97fdf19511ea361ae1c100dd393cc47f8dcfa1e1"
[[constraint]]
name = "golang.org/x/oauth2"
source = "https://github.com/golang/oauth2"
revision = "30785a2c434e431ef7c507b54617d6a951d5f2b4"
[[constraint]]
name = "google.golang.org/api"
source = "https://github.com/google/google-api-go-client"
revision = "e5c227fa33ebccc5a430d863efae400431fc0e85"
[[constraint]]
name = "google.golang.org/appengine"
source = "https://github.com/golang/appengine"
revision = "5bee14b453b4c71be47ec1781b0fa61c2ea182db"
[[constraint]]
name = "cloud.google.com/go"
source = "https://github.com/GoogleCloudPlatform/google-cloud-go"
revision = "2a6493c7a9214bf56c1003bd97443d505cc7e952"
################################
################################
# Transitive dependencies, and overrides
# v1.3.1-coreos.6
[[override]]
name = "github.com/coreos/bbolt"
source = "https://github.com/coreos/bbolt"
revision = "48ea1b39c25fc1bab3506fbc712ecbaa842c4d2d"
# v1.3.0
[[override]]
name = "github.com/grpc-ecosystem/grpc-gateway"
source = "https://github.com/grpc-ecosystem/grpc-gateway"
revision = "8cc3a55af3bcf171a1c23a90c4df9cf591706104"
################################

View File

@ -37,51 +37,7 @@ func startConsul(fs *flags, t *transporterServer) error {
var flags []string var flags []string
switch t.req.DatabaseID { switch t.req.DatabaseID {
case dbtesterpb.DatabaseID_consul__v0_7_5: case dbtesterpb.DatabaseID_consul__v1_0_2:
switch t.req.IPIndex {
case 0: // leader
flags = []string{
"agent",
"-server",
"-data-dir", fs.consulDataDir,
"-bind", peerIPs[t.req.IPIndex],
"-client", peerIPs[t.req.IPIndex],
"-bootstrap-expect", fmt.Sprintf("%d", len(peerIPs)),
}
default:
flags = []string{
"agent",
"-server",
"-data-dir", fs.consulDataDir,
"-bind", peerIPs[t.req.IPIndex],
"-client", peerIPs[t.req.IPIndex],
"-join", peerIPs[0],
}
}
case dbtesterpb.DatabaseID_consul__v0_8_0:
switch t.req.IPIndex {
case 0: // leader
flags = []string{
"agent",
"-server",
"-data-dir", fs.consulDataDir,
"-bind", peerIPs[t.req.IPIndex],
"-client", peerIPs[t.req.IPIndex],
"-bootstrap-expect", fmt.Sprintf("%d", len(peerIPs)),
}
default:
flags = []string{
"agent",
"-server",
"-data-dir", fs.consulDataDir,
"-bind", peerIPs[t.req.IPIndex],
"-client", peerIPs[t.req.IPIndex],
"-join", peerIPs[0],
}
}
case dbtesterpb.DatabaseID_consul__v0_8_4:
switch t.req.IPIndex { switch t.req.IPIndex {
case 0: // leader case 0: // leader
flags = []string{ flags = []string{

View File

@ -23,7 +23,7 @@ import (
"github.com/coreos/dbtester/dbtesterpb" "github.com/coreos/dbtester/dbtesterpb"
) )
// startEtcd starts etcd v2 and v3. // startEtcd starts etcd v3.
func startEtcd(fs *flags, t *transporterServer) error { func startEtcd(fs *flags, t *transporterServer) error {
if !exist(fs.etcdExec) { if !exist(fs.etcdExec) {
return fmt.Errorf("etcd binary %q does not exist", globalFlags.etcdExec) return fmt.Errorf("etcd binary %q does not exist", globalFlags.etcdExec)
@ -48,63 +48,9 @@ func startEtcd(fs *flags, t *transporterServer) error {
var flags []string var flags []string
switch t.req.DatabaseID { switch t.req.DatabaseID {
case dbtesterpb.DatabaseID_etcd__v2_3: case dbtesterpb.DatabaseID_etcd__tip,
flags = []string{ dbtesterpb.DatabaseID_etcd__v3_2,
"--name", names[t.req.IPIndex], dbtesterpb.DatabaseID_etcd__v3_3:
"--data-dir", fs.etcdDataDir,
"--snapshot-count", fmt.Sprintf("%d", t.req.Flag_Etcd_Tip.SnapshotCount),
"--listen-client-urls", clientURLs[t.req.IPIndex],
"--advertise-client-urls", clientURLs[t.req.IPIndex],
"--listen-peer-urls", peerURLs[t.req.IPIndex],
"--initial-advertise-peer-urls", peerURLs[t.req.IPIndex],
"--initial-cluster-token", "mytoken",
"--initial-cluster", strings.Join(members, ","),
"--initial-cluster-state", "new",
}
case dbtesterpb.DatabaseID_etcd__v3_1:
flags = []string{
"--name", names[t.req.IPIndex],
"--data-dir", fs.etcdDataDir,
"--quota-backend-bytes", fmt.Sprintf("%d", t.req.Flag_Etcd_Tip.QuotaSizeBytes),
"--snapshot-count", fmt.Sprintf("%d", t.req.Flag_Etcd_Tip.SnapshotCount),
"--listen-client-urls", clientURLs[t.req.IPIndex],
"--advertise-client-urls", clientURLs[t.req.IPIndex],
"--listen-peer-urls", peerURLs[t.req.IPIndex],
"--initial-advertise-peer-urls", peerURLs[t.req.IPIndex],
"--initial-cluster-token", "mytoken",
"--initial-cluster", strings.Join(members, ","),
"--initial-cluster-state", "new",
}
case dbtesterpb.DatabaseID_etcd__v3_2:
flags = []string{
"--name", names[t.req.IPIndex],
"--data-dir", fs.etcdDataDir,
"--quota-backend-bytes", fmt.Sprintf("%d", t.req.Flag_Etcd_Tip.QuotaSizeBytes),
"--snapshot-count", fmt.Sprintf("%d", t.req.Flag_Etcd_Tip.SnapshotCount),
"--listen-client-urls", clientURLs[t.req.IPIndex],
"--advertise-client-urls", clientURLs[t.req.IPIndex],
"--listen-peer-urls", peerURLs[t.req.IPIndex],
"--initial-advertise-peer-urls", peerURLs[t.req.IPIndex],
"--initial-cluster-token", "mytoken",
"--initial-cluster", strings.Join(members, ","),
"--initial-cluster-state", "new",
}
case dbtesterpb.DatabaseID_etcd__tip:
flags = []string{ flags = []string{
"--name", names[t.req.IPIndex], "--name", names[t.req.IPIndex],
"--data-dir", fs.etcdDataDir, "--data-dir", fs.etcdDataDir,

View File

@ -72,12 +72,6 @@ func init() {
// UPDATE FOR EACH ZOOKEEPER RELEASES! // UPDATE FOR EACH ZOOKEEPER RELEASES!
// Search correct paths with 'find ./zookeeper/lib | sort'. // Search correct paths with 'find ./zookeeper/lib | sort'.
const ( const (
// JavaClassPathZookeeperr349 is the Java class paths of Zookeeper r3.4.9.
JavaClassPathZookeeperr349 = `-cp zookeeper-3.4.9.jar:lib/slf4j-api-1.6.1.jar:lib/slf4j-log4j12-1.6.1.jar:lib/log4j-1.2.16.jar:conf org.apache.zookeeper.server.quorum.QuorumPeerMain`
// JavaClassPathZookeeperr352alpha is the Java class paths of Zookeeper r3.5.2-alpha.
JavaClassPathZookeeperr352alpha = `-cp zookeeper-3.5.2-alpha.jar:lib/slf4j-api-1.7.5.jar:lib/slf4j-log4j12-1.7.5.jar:lib/log4j-1.2.17.jar:conf org.apache.zookeeper.server.quorum.QuorumPeerMain`
// JavaClassPathZookeeperr353beta is the Java class paths of Zookeeper r3.5.3-beta. // JavaClassPathZookeeperr353beta is the Java class paths of Zookeeper r3.5.3-beta.
// http://zookeeper.apache.org/doc/r3.5.3-beta/zookeeperAdmin.html#sc_zkMulitServerSetup // http://zookeeper.apache.org/doc/r3.5.3-beta/zookeeperAdmin.html#sc_zkMulitServerSetup
JavaClassPathZookeeperr353beta = `-cp zookeeper-3.5.3-beta.jar:lib/slf4j-api-1.7.5.jar:lib/slf4j-log4j12-1.7.5.jar:lib/log4j-1.2.17.jar:conf org.apache.zookeeper.server.quorum.QuorumPeerMain` JavaClassPathZookeeperr353beta = `-cp zookeeper-3.5.3-beta.jar:lib/slf4j-api-1.7.5.jar:lib/slf4j-log4j12-1.7.5.jar:lib/log4j-1.2.17.jar:conf org.apache.zookeeper.server.quorum.QuorumPeerMain`
@ -103,22 +97,6 @@ func startZookeeper(fs *flags, t *transporterServer) error {
ipath := filepath.Join(fs.zkDataDir, "myid") ipath := filepath.Join(fs.zkDataDir, "myid")
switch t.req.DatabaseID { switch t.req.DatabaseID {
case dbtesterpb.DatabaseID_zookeeper__r3_4_9:
if t.req.Flag_Zookeeper_R3_4_9 == nil {
return fmt.Errorf("request 'Flag_Zookeeper_R3_4_9' is nil")
}
plog.Infof("writing Zookeeper myid file %d to %s", t.req.Flag_Zookeeper_R3_4_9.MyID, ipath)
if err := toFile(fmt.Sprintf("%d", t.req.Flag_Zookeeper_R3_4_9.MyID), ipath); err != nil {
return err
}
case dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha:
if t.req.Flag_Zookeeper_R3_5_2Alpha == nil {
return fmt.Errorf("request 'Flag_Zookeeper_R3_5_2Alpha' is nil")
}
plog.Infof("writing Zookeeper myid file %d to %s", t.req.Flag_Zookeeper_R3_5_2Alpha.MyID, ipath)
if err := toFile(fmt.Sprintf("%d", t.req.Flag_Zookeeper_R3_5_2Alpha.MyID), ipath); err != nil {
return err
}
case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta: case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
if t.req.Flag_Zookeeper_R3_5_3Beta == nil { if t.req.Flag_Zookeeper_R3_5_3Beta == nil {
return fmt.Errorf("request 'Flag_Zookeeper_R3_5_3Beta' is nil") return fmt.Errorf("request 'Flag_Zookeeper_R3_5_3Beta' is nil")
@ -138,28 +116,6 @@ func startZookeeper(fs *flags, t *transporterServer) error {
peers = append(peers, ZookeeperPeer{MyID: i + 1, IP: peerIPs[i]}) peers = append(peers, ZookeeperPeer{MyID: i + 1, IP: peerIPs[i]})
} }
switch t.req.DatabaseID { switch t.req.DatabaseID {
case dbtesterpb.DatabaseID_zookeeper__r3_4_9:
cfg = ZookeeperConfig{
TickTime: t.req.Flag_Zookeeper_R3_4_9.TickTime,
DataDir: fs.zkDataDir,
ClientPort: t.req.Flag_Zookeeper_R3_4_9.ClientPort,
InitLimit: t.req.Flag_Zookeeper_R3_4_9.InitLimit,
SyncLimit: t.req.Flag_Zookeeper_R3_4_9.SyncLimit,
MaxClientConnections: t.req.Flag_Zookeeper_R3_4_9.MaxClientConnections,
Peers: peers,
SnapCount: t.req.Flag_Zookeeper_R3_4_9.SnapCount,
}
case dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha:
cfg = ZookeeperConfig{
TickTime: t.req.Flag_Zookeeper_R3_5_2Alpha.TickTime,
DataDir: fs.zkDataDir,
ClientPort: t.req.Flag_Zookeeper_R3_5_2Alpha.ClientPort,
InitLimit: t.req.Flag_Zookeeper_R3_5_2Alpha.InitLimit,
SyncLimit: t.req.Flag_Zookeeper_R3_5_2Alpha.SyncLimit,
MaxClientConnections: t.req.Flag_Zookeeper_R3_5_2Alpha.MaxClientConnections,
Peers: peers,
SnapCount: t.req.Flag_Zookeeper_R3_5_2Alpha.SnapCount,
}
case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta: case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
cfg = ZookeeperConfig{ cfg = ZookeeperConfig{
TickTime: t.req.Flag_Zookeeper_R3_5_3Beta.TickTime, TickTime: t.req.Flag_Zookeeper_R3_5_3Beta.TickTime,
@ -187,56 +143,6 @@ func startZookeeper(fs *flags, t *transporterServer) error {
var flagString string var flagString string
switch t.req.DatabaseID { switch t.req.DatabaseID {
case dbtesterpb.DatabaseID_zookeeper__r3_4_9:
if t.req.Flag_Zookeeper_R3_4_9.JavaDJuteMaxBuffer != 0 {
if len(flagString) > 0 {
flagString += " "
}
flagString += fmt.Sprintf("-Djute.maxbuffer=%d", t.req.Flag_Zookeeper_R3_4_9.JavaDJuteMaxBuffer)
}
if t.req.Flag_Zookeeper_R3_4_9.JavaDJuteMaxBuffer != 0 {
if len(flagString) > 0 {
flagString += " "
}
flagString += fmt.Sprintf("-Xms%s", t.req.Flag_Zookeeper_R3_4_9.JavaXms)
}
if t.req.Flag_Zookeeper_R3_4_9.JavaDJuteMaxBuffer != 0 {
if len(flagString) > 0 {
flagString += " "
}
flagString += fmt.Sprintf("-Xmx%s", t.req.Flag_Zookeeper_R3_4_9.JavaXmx)
}
// -Djute.maxbuffer=33554432 -Xms50G -Xmx50G
if len(flagString) > 0 {
flagString += " "
}
flagString += JavaClassPathZookeeperr349
case dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha:
if t.req.Flag_Zookeeper_R3_5_2Alpha.JavaDJuteMaxBuffer != 0 {
if len(flagString) > 0 {
flagString += " "
}
flagString += fmt.Sprintf("-Djute.maxbuffer=%d", t.req.Flag_Zookeeper_R3_5_2Alpha.JavaDJuteMaxBuffer)
}
if t.req.Flag_Zookeeper_R3_5_2Alpha.JavaDJuteMaxBuffer != 0 {
if len(flagString) > 0 {
flagString += " "
}
flagString += fmt.Sprintf("-Xms%s", t.req.Flag_Zookeeper_R3_5_2Alpha.JavaXms)
}
if t.req.Flag_Zookeeper_R3_5_2Alpha.JavaDJuteMaxBuffer != 0 {
if len(flagString) > 0 {
flagString += " "
}
flagString += fmt.Sprintf("-Xmx%s", t.req.Flag_Zookeeper_R3_5_2Alpha.JavaXmx)
}
// -Djute.maxbuffer=33554432 -Xms50G -Xmx50G
if len(flagString) > 0 {
flagString += " "
}
flagString += JavaClassPathZookeeperr352alpha
case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta: case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
if t.req.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer != 0 { if t.req.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer != 0 {
if len(flagString) > 0 { if len(flagString) > 0 {

View File

@ -100,21 +100,18 @@ func (t *transporterServer) Transfer(ctx context.Context, req *dbtesterpb.Reques
plog.Infof("system metrics CSV path: %q", globalFlags.systemMetricsCSV) plog.Infof("system metrics CSV path: %q", globalFlags.systemMetricsCSV)
switch req.DatabaseID { switch req.DatabaseID {
case dbtesterpb.DatabaseID_etcd__v2_3, case dbtesterpb.DatabaseID_etcd__tip,
dbtesterpb.DatabaseID_etcd__tip: dbtesterpb.DatabaseID_etcd__v3_2,
dbtesterpb.DatabaseID_etcd__v3_3:
plog.Infof("etcd executable binary path: %q", globalFlags.etcdExec) plog.Infof("etcd executable binary path: %q", globalFlags.etcdExec)
plog.Infof("etcd data directory: %q", globalFlags.etcdDataDir) plog.Infof("etcd data directory: %q", globalFlags.etcdDataDir)
case dbtesterpb.DatabaseID_zookeeper__r3_4_9, case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha,
dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
plog.Infof("Zookeeper working directory: %q", globalFlags.zkWorkDir) plog.Infof("Zookeeper working directory: %q", globalFlags.zkWorkDir)
plog.Infof("Zookeeper data directory: %q", globalFlags.zkDataDir) plog.Infof("Zookeeper data directory: %q", globalFlags.zkDataDir)
plog.Infof("Zookeeper configuration path: %q", globalFlags.zkConfig) plog.Infof("Zookeeper configuration path: %q", globalFlags.zkConfig)
case dbtesterpb.DatabaseID_consul__v0_7_5, case dbtesterpb.DatabaseID_consul__v1_0_2:
dbtesterpb.DatabaseID_consul__v0_8_0,
dbtesterpb.DatabaseID_consul__v0_8_4:
plog.Infof("Consul executable binary path: %q", globalFlags.consulExec) plog.Infof("Consul executable binary path: %q", globalFlags.consulExec)
plog.Infof("Consul data directory: %q", globalFlags.consulDataDir) plog.Infof("Consul data directory: %q", globalFlags.consulDataDir)
@ -139,10 +136,9 @@ func (t *transporterServer) Transfer(ctx context.Context, req *dbtesterpb.Reques
switch req.Operation { switch req.Operation {
case dbtesterpb.Operation_Start: case dbtesterpb.Operation_Start:
switch t.req.DatabaseID { switch t.req.DatabaseID {
case dbtesterpb.DatabaseID_etcd__v2_3, case dbtesterpb.DatabaseID_etcd__tip,
dbtesterpb.DatabaseID_etcd__v3_1,
dbtesterpb.DatabaseID_etcd__v3_2, dbtesterpb.DatabaseID_etcd__v3_2,
dbtesterpb.DatabaseID_etcd__tip, dbtesterpb.DatabaseID_etcd__v3_3,
dbtesterpb.DatabaseID_zetcd__beta, dbtesterpb.DatabaseID_zetcd__beta,
dbtesterpb.DatabaseID_cetcd__beta: dbtesterpb.DatabaseID_cetcd__beta:
if err := startEtcd(&globalFlags, t); err != nil { if err := startEtcd(&globalFlags, t); err != nil {
@ -177,16 +173,12 @@ func (t *transporterServer) Transfer(ctx context.Context, req *dbtesterpb.Reques
plog.Infof("exiting %q", t.proxyCmd.Path) plog.Infof("exiting %q", t.proxyCmd.Path)
}() }()
} }
case dbtesterpb.DatabaseID_zookeeper__r3_4_9, case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha,
dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
if err := startZookeeper(&globalFlags, t); err != nil { if err := startZookeeper(&globalFlags, t); err != nil {
plog.Errorf("startZookeeper error %v", err) plog.Errorf("startZookeeper error %v", err)
return nil, err return nil, err
} }
case dbtesterpb.DatabaseID_consul__v0_7_5, case dbtesterpb.DatabaseID_consul__v1_0_2:
dbtesterpb.DatabaseID_consul__v0_8_0,
dbtesterpb.DatabaseID_consul__v0_8_4:
if err := startConsul(&globalFlags, t); err != nil { if err := startConsul(&globalFlags, t); err != nil {
plog.Errorf("startConsul error %v", err) plog.Errorf("startConsul error %v", err)
return nil, err return nil, err
@ -289,26 +281,16 @@ func (t *transporterServer) Transfer(ctx context.Context, req *dbtesterpb.Reques
func measureDatabasSize(flg flags, rdb dbtesterpb.DatabaseID) (int64, error) { func measureDatabasSize(flg flags, rdb dbtesterpb.DatabaseID) (int64, error) {
switch rdb { switch rdb {
case dbtesterpb.DatabaseID_etcd__v2_3: case dbtesterpb.DatabaseID_etcd__tip,
dbtesterpb.DatabaseID_etcd__v3_2,
dbtesterpb.DatabaseID_etcd__v3_3,
dbtesterpb.DatabaseID_cetcd__beta,
dbtesterpb.DatabaseID_zetcd__beta:
return fileinspect.Size(flg.etcdDataDir) return fileinspect.Size(flg.etcdDataDir)
case dbtesterpb.DatabaseID_etcd__tip:
return fileinspect.Size(flg.etcdDataDir)
case dbtesterpb.DatabaseID_zookeeper__r3_4_9:
return fileinspect.Size(flg.zkDataDir)
case dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha:
return fileinspect.Size(flg.zkDataDir)
case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta: case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
return fileinspect.Size(flg.zkDataDir) return fileinspect.Size(flg.zkDataDir)
case dbtesterpb.DatabaseID_consul__v0_7_5: case dbtesterpb.DatabaseID_consul__v1_0_2:
return fileinspect.Size(flg.consulDataDir) return fileinspect.Size(flg.consulDataDir)
case dbtesterpb.DatabaseID_consul__v0_8_0:
return fileinspect.Size(flg.consulDataDir)
case dbtesterpb.DatabaseID_consul__v0_8_4:
return fileinspect.Size(flg.consulDataDir)
case dbtesterpb.DatabaseID_cetcd__beta:
return fileinspect.Size(flg.etcdDataDir)
case dbtesterpb.DatabaseID_zetcd__beta:
return fileinspect.Size(flg.etcdDataDir)
default: default:
return 0, fmt.Errorf("uknown %q", rdb) return 0, fmt.Errorf("uknown %q", rdb)
} }

View File

@ -19,11 +19,11 @@ import (
"github.com/coreos/dbtester/dbtesterpb" "github.com/coreos/dbtester/dbtesterpb"
"github.com/gonum/plot"
"github.com/gonum/plot/plotter"
"github.com/gonum/plot/plotutil"
"github.com/gonum/plot/vg"
"github.com/gyuho/dataframe" "github.com/gyuho/dataframe"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/plotutil"
"gonum.org/v1/plot/vg"
) )
var ( var (

View File

@ -125,9 +125,9 @@ func ReadConfig(fpath string, analyze bool) (*Config, error) {
} }
for databaseID, ctrl := range cfg.DatabaseIDToConfigClientMachineAgentControl { for databaseID, ctrl := range cfg.DatabaseIDToConfigClientMachineAgentControl {
if databaseID != dbtesterpb.DatabaseID_etcd__v3_1.String() && if databaseID != dbtesterpb.DatabaseID_etcd__tip.String() &&
databaseID != dbtesterpb.DatabaseID_etcd__v3_2.String() && databaseID != dbtesterpb.DatabaseID_etcd__v3_2.String() &&
databaseID != dbtesterpb.DatabaseID_etcd__tip.String() && databaseID != dbtesterpb.DatabaseID_etcd__v3_3.String() &&
ctrl.ConfigClientMachineBenchmarkOptions.ConnectionNumber != ctrl.ConfigClientMachineBenchmarkOptions.ClientNumber { ctrl.ConfigClientMachineBenchmarkOptions.ConnectionNumber != ctrl.ConfigClientMachineBenchmarkOptions.ClientNumber {
return nil, fmt.Errorf("%q got connected %d != clients %d", databaseID, ctrl.ConfigClientMachineBenchmarkOptions.ConnectionNumber, ctrl.ConfigClientMachineBenchmarkOptions.ClientNumber) return nil, fmt.Errorf("%q got connected %d != clients %d", databaseID, ctrl.ConfigClientMachineBenchmarkOptions.ConnectionNumber, ctrl.ConfigClientMachineBenchmarkOptions.ClientNumber)
} }
@ -148,32 +148,20 @@ func ReadConfig(fpath string, analyze bool) (*Config, error) {
defaultZookeeperMaxClientConnections int64 = 5000 defaultZookeeperMaxClientConnections int64 = 5000
) )
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v2_3.String()]; ok { if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()]; ok {
if v.AgentPortToConnect == 0 { if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort v.AgentPortToConnect = defaultAgentPort
} }
if v.DatabasePortToConnect == 0 { if v.DatabasePortToConnect == 0 {
v.DatabasePortToConnect = defaultEtcdClientPort v.DatabasePortToConnect = defaultEtcdClientPort
} }
if v.Flag_Etcd_V2_3.SnapshotCount == 0 { if v.Flag_Etcd_Tip.SnapshotCount == 0 {
v.Flag_Etcd_V2_3.SnapshotCount = defaultEtcdSnapshotCount v.Flag_Etcd_Tip.SnapshotCount = defaultEtcdSnapshotCount
} }
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v2_3.String()] = v if v.Flag_Etcd_Tip.QuotaSizeBytes == 0 {
} v.Flag_Etcd_Tip.QuotaSizeBytes = defaultEtcdQuotaSizeBytes
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_1.String()]; ok {
if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort
} }
if v.DatabasePortToConnect == 0 { cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()] = v
v.DatabasePortToConnect = defaultEtcdClientPort
}
if v.Flag_Etcd_V3_1.SnapshotCount == 0 {
v.Flag_Etcd_V3_1.SnapshotCount = defaultEtcdSnapshotCount
}
if v.Flag_Etcd_V3_1.QuotaSizeBytes == 0 {
v.Flag_Etcd_V3_1.QuotaSizeBytes = defaultEtcdQuotaSizeBytes
}
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_1.String()] = v
} }
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()]; ok { if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()]; ok {
if v.AgentPortToConnect == 0 { if v.AgentPortToConnect == 0 {
@ -190,75 +178,22 @@ func ReadConfig(fpath string, analyze bool) (*Config, error) {
} }
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()] = v cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()] = v
} }
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()]; ok { if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_3.String()]; ok {
if v.AgentPortToConnect == 0 { if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort v.AgentPortToConnect = defaultAgentPort
} }
if v.DatabasePortToConnect == 0 { if v.DatabasePortToConnect == 0 {
v.DatabasePortToConnect = defaultEtcdClientPort v.DatabasePortToConnect = defaultEtcdClientPort
} }
if v.Flag_Etcd_Tip.SnapshotCount == 0 { if v.Flag_Etcd_V3_3.SnapshotCount == 0 {
v.Flag_Etcd_Tip.SnapshotCount = defaultEtcdSnapshotCount v.Flag_Etcd_V3_3.SnapshotCount = defaultEtcdSnapshotCount
} }
if v.Flag_Etcd_Tip.QuotaSizeBytes == 0 { if v.Flag_Etcd_V3_3.QuotaSizeBytes == 0 {
v.Flag_Etcd_Tip.QuotaSizeBytes = defaultEtcdQuotaSizeBytes v.Flag_Etcd_V3_3.QuotaSizeBytes = defaultEtcdQuotaSizeBytes
} }
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()] = v cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_3.String()] = v
} }
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_4_9.String()]; ok {
if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort
}
if v.DatabasePortToConnect == 0 {
v.DatabasePortToConnect = defaultZookeeperClientPort
}
v.Flag_Zookeeper_R3_4_9.ClientPort = v.DatabasePortToConnect
if v.Flag_Zookeeper_R3_4_9.TickTime == 0 {
v.Flag_Zookeeper_R3_4_9.TickTime = defaultZookeeperTickTime
}
if v.Flag_Zookeeper_R3_4_9.InitLimit == 0 {
v.Flag_Zookeeper_R3_4_9.InitLimit = defaultZookeeperInitLimit
}
if v.Flag_Zookeeper_R3_4_9.SyncLimit == 0 {
v.Flag_Zookeeper_R3_4_9.SyncLimit = defaultZookeeperSyncLimit
}
if v.Flag_Zookeeper_R3_4_9.SnapCount == 0 {
v.Flag_Zookeeper_R3_4_9.SnapCount = defaultZookeeperSnapCount
}
if v.Flag_Zookeeper_R3_4_9.MaxClientConnections == 0 {
v.Flag_Zookeeper_R3_4_9.MaxClientConnections = defaultZookeeperMaxClientConnections
}
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_4_9.String()] = v
}
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha.String()]; ok {
if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort
}
if v.DatabasePortToConnect == 0 {
v.DatabasePortToConnect = defaultZookeeperClientPort
}
v.Flag_Zookeeper_R3_5_2Alpha.ClientPort = v.DatabasePortToConnect
if v.Flag_Zookeeper_R3_5_2Alpha.TickTime == 0 {
v.Flag_Zookeeper_R3_5_2Alpha.TickTime = defaultZookeeperTickTime
}
if v.Flag_Zookeeper_R3_5_2Alpha.TickTime == 0 {
v.Flag_Zookeeper_R3_5_2Alpha.TickTime = defaultZookeeperTickTime
}
if v.Flag_Zookeeper_R3_5_2Alpha.InitLimit == 0 {
v.Flag_Zookeeper_R3_5_2Alpha.InitLimit = defaultZookeeperInitLimit
}
if v.Flag_Zookeeper_R3_5_2Alpha.SyncLimit == 0 {
v.Flag_Zookeeper_R3_5_2Alpha.SyncLimit = defaultZookeeperSyncLimit
}
if v.Flag_Zookeeper_R3_5_2Alpha.SnapCount == 0 {
v.Flag_Zookeeper_R3_5_2Alpha.SnapCount = defaultZookeeperSnapCount
}
if v.Flag_Zookeeper_R3_5_2Alpha.MaxClientConnections == 0 {
v.Flag_Zookeeper_R3_5_2Alpha.MaxClientConnections = defaultZookeeperMaxClientConnections
}
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha.String()] = v
}
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta.String()]; ok { if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta.String()]; ok {
if v.AgentPortToConnect == 0 { if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort v.AgentPortToConnect = defaultAgentPort
@ -288,50 +223,30 @@ func ReadConfig(fpath string, analyze bool) (*Config, error) {
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta.String()] = v cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta.String()] = v
} }
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v0_7_5.String()]; ok { if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v1_0_2.String()]; ok {
if v.AgentPortToConnect == 0 { if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort v.AgentPortToConnect = defaultAgentPort
} }
if v.DatabasePortToConnect == 0 { if v.DatabasePortToConnect == 0 {
v.DatabasePortToConnect = defaultConsulClientPort v.DatabasePortToConnect = defaultConsulClientPort
} }
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v0_7_5.String()] = v cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v1_0_2.String()] = v
}
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v0_8_0.String()]; ok {
if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort
}
if v.DatabasePortToConnect == 0 {
v.DatabasePortToConnect = defaultConsulClientPort
}
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v0_8_0.String()] = v
}
if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v0_8_4.String()]; ok {
if v.AgentPortToConnect == 0 {
v.AgentPortToConnect = defaultAgentPort
}
if v.DatabasePortToConnect == 0 {
v.DatabasePortToConnect = defaultConsulClientPort
}
cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v0_8_4.String()] = v
} }
// need etcd configs since it's backed by etcd // need etcd configs since it's backed by etcd
if _, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zetcd__beta.String()]; ok { if _, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zetcd__beta.String()]; ok {
_, ok1 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v2_3.String()] _, okTip := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()]
_, ok2 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_1.String()] _, ok32 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()]
_, ok3 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()] _, ok33 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_3.String()]
_, ok4 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()] if !okTip && !ok32 && !ok33 {
if !ok1 && !ok2 && !ok3 && !ok4 {
return nil, fmt.Errorf("got %q config, but no etcd config is given", dbtesterpb.DatabaseID_zetcd__beta.String()) return nil, fmt.Errorf("got %q config, but no etcd config is given", dbtesterpb.DatabaseID_zetcd__beta.String())
} }
} }
if _, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_cetcd__beta.String()]; ok { if _, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_cetcd__beta.String()]; ok {
_, ok1 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v2_3.String()] _, okTip := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()]
_, ok2 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_1.String()] _, ok32 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()]
_, ok3 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()] _, ok33 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_3.String()]
_, ok4 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()] if !okTip && !ok32 && !ok33 {
if !ok1 && !ok2 && !ok3 && !ok4 {
return nil, fmt.Errorf("got %q config, but no etcd config is given", dbtesterpb.DatabaseID_cetcd__beta.String()) return nil, fmt.Errorf("got %q config, but no etcd config is given", dbtesterpb.DatabaseID_cetcd__beta.String())
} }
} }
@ -382,18 +297,14 @@ func (cfg *Config) ToRequest(databaseID string, op dbtesterpb.Operation, idx int
} }
switch req.DatabaseID { switch req.DatabaseID {
case dbtesterpb.DatabaseID_etcd__v2_3: case dbtesterpb.DatabaseID_etcd__tip:
req.Flag_Etcd_V2_3 = &dbtesterpb.Flag_Etcd_V2_3{ if gcfg.Flag_Etcd_Tip.QuotaSizeBytes > maxEtcdQuotaSize {
SnapshotCount: gcfg.Flag_Etcd_V2_3.SnapshotCount, err = fmt.Errorf("maximum etcd quota is 8 GB (%d), got %d", maxEtcdQuotaSize, gcfg.Flag_Etcd_Tip.QuotaSizeBytes)
}
case dbtesterpb.DatabaseID_etcd__v3_1:
if gcfg.Flag_Etcd_V3_1.QuotaSizeBytes > maxEtcdQuotaSize {
err = fmt.Errorf("maximum etcd quota is 8 GB (%d), got %d", maxEtcdQuotaSize, gcfg.Flag_Etcd_V3_1.QuotaSizeBytes)
return return
} }
req.Flag_Etcd_V3_1 = &dbtesterpb.Flag_Etcd_V3_1{ req.Flag_Etcd_Tip = &dbtesterpb.Flag_Etcd_Tip{
SnapshotCount: gcfg.Flag_Etcd_V3_1.SnapshotCount, SnapshotCount: gcfg.Flag_Etcd_Tip.SnapshotCount,
QuotaSizeBytes: gcfg.Flag_Etcd_V3_1.QuotaSizeBytes, QuotaSizeBytes: gcfg.Flag_Etcd_Tip.QuotaSizeBytes,
} }
case dbtesterpb.DatabaseID_etcd__v3_2: case dbtesterpb.DatabaseID_etcd__v3_2:
if gcfg.Flag_Etcd_V3_2.QuotaSizeBytes > maxEtcdQuotaSize { if gcfg.Flag_Etcd_V3_2.QuotaSizeBytes > maxEtcdQuotaSize {
@ -404,42 +315,16 @@ func (cfg *Config) ToRequest(databaseID string, op dbtesterpb.Operation, idx int
SnapshotCount: gcfg.Flag_Etcd_V3_2.SnapshotCount, SnapshotCount: gcfg.Flag_Etcd_V3_2.SnapshotCount,
QuotaSizeBytes: gcfg.Flag_Etcd_V3_2.QuotaSizeBytes, QuotaSizeBytes: gcfg.Flag_Etcd_V3_2.QuotaSizeBytes,
} }
case dbtesterpb.DatabaseID_etcd__tip: case dbtesterpb.DatabaseID_etcd__v3_3:
if gcfg.Flag_Etcd_Tip.QuotaSizeBytes > maxEtcdQuotaSize { if gcfg.Flag_Etcd_V3_3.QuotaSizeBytes > maxEtcdQuotaSize {
err = fmt.Errorf("maximum etcd quota is 8 GB (%d), got %d", maxEtcdQuotaSize, gcfg.Flag_Etcd_Tip.QuotaSizeBytes) err = fmt.Errorf("maximum etcd quota is 8 GB (%d), got %d", maxEtcdQuotaSize, gcfg.Flag_Etcd_V3_3.QuotaSizeBytes)
return return
} }
req.Flag_Etcd_Tip = &dbtesterpb.Flag_Etcd_Tip{ req.Flag_Etcd_V3_3 = &dbtesterpb.Flag_Etcd_V3_3{
SnapshotCount: gcfg.Flag_Etcd_Tip.SnapshotCount, SnapshotCount: gcfg.Flag_Etcd_V3_3.SnapshotCount,
QuotaSizeBytes: gcfg.Flag_Etcd_Tip.QuotaSizeBytes, QuotaSizeBytes: gcfg.Flag_Etcd_V3_3.QuotaSizeBytes,
} }
case dbtesterpb.DatabaseID_zookeeper__r3_4_9:
req.Flag_Zookeeper_R3_4_9 = &dbtesterpb.Flag_Zookeeper_R3_4_9{
JavaDJuteMaxBuffer: gcfg.Flag_Zookeeper_R3_4_9.JavaDJuteMaxBuffer,
JavaXms: gcfg.Flag_Zookeeper_R3_4_9.JavaXms,
JavaXmx: gcfg.Flag_Zookeeper_R3_4_9.JavaXmx,
MyID: uint32(idx + 1),
ClientPort: gcfg.Flag_Zookeeper_R3_4_9.ClientPort,
TickTime: gcfg.Flag_Zookeeper_R3_4_9.TickTime,
InitLimit: gcfg.Flag_Zookeeper_R3_4_9.InitLimit,
SyncLimit: gcfg.Flag_Zookeeper_R3_4_9.SyncLimit,
SnapCount: gcfg.Flag_Zookeeper_R3_4_9.SnapCount,
MaxClientConnections: gcfg.Flag_Zookeeper_R3_4_9.MaxClientConnections,
}
case dbtesterpb.DatabaseID_zookeeper__r3_5_2_alpha:
req.Flag_Zookeeper_R3_5_2Alpha = &dbtesterpb.Flag_Zookeeper_R3_5_2Alpha{
JavaDJuteMaxBuffer: gcfg.Flag_Zookeeper_R3_5_2Alpha.JavaDJuteMaxBuffer,
JavaXms: gcfg.Flag_Zookeeper_R3_5_2Alpha.JavaXms,
JavaXmx: gcfg.Flag_Zookeeper_R3_5_2Alpha.JavaXmx,
MyID: uint32(idx + 1),
ClientPort: gcfg.Flag_Zookeeper_R3_5_2Alpha.ClientPort,
TickTime: gcfg.Flag_Zookeeper_R3_5_2Alpha.TickTime,
InitLimit: gcfg.Flag_Zookeeper_R3_5_2Alpha.InitLimit,
SyncLimit: gcfg.Flag_Zookeeper_R3_5_2Alpha.SyncLimit,
SnapCount: gcfg.Flag_Zookeeper_R3_5_2Alpha.SnapCount,
MaxClientConnections: gcfg.Flag_Zookeeper_R3_5_2Alpha.MaxClientConnections,
}
case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta: case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
req.Flag_Zookeeper_R3_5_3Beta = &dbtesterpb.Flag_Zookeeper_R3_5_3Beta{ req.Flag_Zookeeper_R3_5_3Beta = &dbtesterpb.Flag_Zookeeper_R3_5_3Beta{
JavaDJuteMaxBuffer: gcfg.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer, JavaDJuteMaxBuffer: gcfg.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer,
@ -454,9 +339,7 @@ func (cfg *Config) ToRequest(databaseID string, op dbtesterpb.Operation, idx int
MaxClientConnections: gcfg.Flag_Zookeeper_R3_5_3Beta.MaxClientConnections, MaxClientConnections: gcfg.Flag_Zookeeper_R3_5_3Beta.MaxClientConnections,
} }
case dbtesterpb.DatabaseID_consul__v0_7_5: case dbtesterpb.DatabaseID_consul__v1_0_2:
case dbtesterpb.DatabaseID_consul__v0_8_0:
case dbtesterpb.DatabaseID_consul__v0_8_4:
case dbtesterpb.DatabaseID_zetcd__beta: case dbtesterpb.DatabaseID_zetcd__beta:
case dbtesterpb.DatabaseID_cetcd__beta: case dbtesterpb.DatabaseID_cetcd__beta:

View File

@ -26,16 +26,11 @@
ConfigClientMachineBenchmarkSteps ConfigClientMachineBenchmarkSteps
ConfigClientMachineAgentControl ConfigClientMachineAgentControl
Flag_Cetcd_Beta Flag_Cetcd_Beta
Flag_Consul_V0_7_5 Flag_Consul_V1_0_2
Flag_Consul_V0_8_0
Flag_Consul_V0_8_4
Flag_Etcd_V2_3
Flag_Etcd_V3_1
Flag_Etcd_V3_2
Flag_Etcd_Tip Flag_Etcd_Tip
Flag_Etcd_V3_2
Flag_Etcd_V3_3
Flag_Zetcd_Beta Flag_Zetcd_Beta
Flag_Zookeeper_R3_4_9
Flag_Zookeeper_R3_5_2Alpha
Flag_Zookeeper_R3_5_3Beta Flag_Zookeeper_R3_5_3Beta
Request Request
Response Response
@ -435,24 +430,6 @@ func (m *ConfigAnalyzeMachineREADME) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func encodeFixed64ConfigAnalyzeMachine(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32ConfigAnalyzeMachine(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintConfigAnalyzeMachine(dAtA []byte, offset int, v uint64) int { func encodeVarintConfigAnalyzeMachine(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)

View File

@ -88,16 +88,11 @@ type ConfigClientMachineAgentControl struct {
AgentEndpoints []string `protobuf:"bytes,7,rep,name=AgentEndpoints" json:"AgentEndpoints,omitempty" yaml:"agent_endpoints"` AgentEndpoints []string `protobuf:"bytes,7,rep,name=AgentEndpoints" json:"AgentEndpoints,omitempty" yaml:"agent_endpoints"`
DatabasePortToConnect int64 `protobuf:"varint,8,opt,name=DatabasePortToConnect,proto3" json:"DatabasePortToConnect,omitempty" yaml:"database_port_to_connect"` DatabasePortToConnect int64 `protobuf:"varint,8,opt,name=DatabasePortToConnect,proto3" json:"DatabasePortToConnect,omitempty" yaml:"database_port_to_connect"`
DatabaseEndpoints []string `protobuf:"bytes,9,rep,name=DatabaseEndpoints" json:"DatabaseEndpoints,omitempty" yaml:"database_endpoints"` DatabaseEndpoints []string `protobuf:"bytes,9,rep,name=DatabaseEndpoints" json:"DatabaseEndpoints,omitempty" yaml:"database_endpoints"`
Flag_Etcd_V2_3 *Flag_Etcd_V2_3 `protobuf:"bytes,100,opt,name=flag__etcd__v2_3,json=flagEtcdV23" json:"flag__etcd__v2_3,omitempty" yaml:"etcd__v2_3"` Flag_Etcd_Tip *Flag_Etcd_Tip `protobuf:"bytes,100,opt,name=flag__etcd__tip,json=flagEtcdTip" json:"flag__etcd__tip,omitempty" yaml:"etcd__tip"`
Flag_Etcd_V3_1 *Flag_Etcd_V3_1 `protobuf:"bytes,101,opt,name=flag__etcd__v3_1,json=flagEtcdV31" json:"flag__etcd__v3_1,omitempty" yaml:"etcd__v3_1"` Flag_Etcd_V3_2 *Flag_Etcd_V3_2 `protobuf:"bytes,101,opt,name=flag__etcd__v3_2,json=flagEtcdV32" json:"flag__etcd__v3_2,omitempty" yaml:"etcd__v3_2"`
Flag_Etcd_V3_2 *Flag_Etcd_V3_2 `protobuf:"bytes,102,opt,name=flag__etcd__v3_2,json=flagEtcdV32" json:"flag__etcd__v3_2,omitempty" yaml:"etcd__v3_2"` Flag_Etcd_V3_3 *Flag_Etcd_V3_3 `protobuf:"bytes,102,opt,name=flag__etcd__v3_3,json=flagEtcdV33" json:"flag__etcd__v3_3,omitempty" yaml:"etcd__v3_3"`
Flag_Etcd_Tip *Flag_Etcd_Tip `protobuf:"bytes,103,opt,name=flag__etcd__tip,json=flagEtcdTip" json:"flag__etcd__tip,omitempty" yaml:"etcd__tip"` Flag_Zookeeper_R3_5_3Beta *Flag_Zookeeper_R3_5_3Beta `protobuf:"bytes,200,opt,name=flag__zookeeper__r3_5_3_beta,json=flagZookeeperR353Beta" json:"flag__zookeeper__r3_5_3_beta,omitempty" yaml:"zookeeper__r3_5_3_beta"`
Flag_Zookeeper_R3_4_9 *Flag_Zookeeper_R3_4_9 `protobuf:"bytes,200,opt,name=flag__zookeeper__r3_4_9,json=flagZookeeperR349" json:"flag__zookeeper__r3_4_9,omitempty" yaml:"zookeeper__r3_4_9"` Flag_Consul_V1_0_2 *Flag_Consul_V1_0_2 `protobuf:"bytes,300,opt,name=flag__consul__v1_0_2,json=flagConsulV102" json:"flag__consul__v1_0_2,omitempty" yaml:"consul__v1_0_2"`
Flag_Zookeeper_R3_5_2Alpha *Flag_Zookeeper_R3_5_2Alpha `protobuf:"bytes,201,opt,name=flag__zookeeper__r3_5_2_alpha,json=flagZookeeperR352Alpha" json:"flag__zookeeper__r3_5_2_alpha,omitempty" yaml:"zookeeper__r3_5_2_alpha"`
Flag_Zookeeper_R3_5_3Beta *Flag_Zookeeper_R3_5_3Beta `protobuf:"bytes,202,opt,name=flag__zookeeper__r3_5_3_beta,json=flagZookeeperR353Beta" json:"flag__zookeeper__r3_5_3_beta,omitempty" yaml:"zookeeper__r3_5_3_beta"`
Flag_Consul_V0_7_5 *Flag_Consul_V0_7_5 `protobuf:"bytes,300,opt,name=flag__consul__v0_7_5,json=flagConsulV075" json:"flag__consul__v0_7_5,omitempty" yaml:"consul__v0_7_5"`
Flag_Consul_V0_8_0 *Flag_Consul_V0_8_0 `protobuf:"bytes,301,opt,name=flag__consul__v0_8_0,json=flagConsulV080" json:"flag__consul__v0_8_0,omitempty" yaml:"consul__v0_8_0"`
Flag_Consul_V0_8_4 *Flag_Consul_V0_8_4 `protobuf:"bytes,302,opt,name=flag__consul__v0_8_4,json=flagConsulV084" json:"flag__consul__v0_8_4,omitempty" yaml:"consul__v0_8_4"`
Flag_Cetcd_Beta *Flag_Cetcd_Beta `protobuf:"bytes,400,opt,name=flag__cetcd__beta,json=flagCetcdBeta" json:"flag__cetcd__beta,omitempty" yaml:"cetcd__beta"` Flag_Cetcd_Beta *Flag_Cetcd_Beta `protobuf:"bytes,400,opt,name=flag__cetcd__beta,json=flagCetcdBeta" json:"flag__cetcd__beta,omitempty" yaml:"cetcd__beta"`
Flag_Zetcd_Beta *Flag_Zetcd_Beta `protobuf:"bytes,500,opt,name=flag__zetcd__beta,json=flagZetcdBeta" json:"flag__zetcd__beta,omitempty" yaml:"zetcd__beta"` Flag_Zetcd_Beta *Flag_Zetcd_Beta `protobuf:"bytes,500,opt,name=flag__zetcd__beta,json=flagZetcdBeta" json:"flag__zetcd__beta,omitempty" yaml:"zetcd__beta"`
ConfigClientMachineBenchmarkOptions *ConfigClientMachineBenchmarkOptions `protobuf:"bytes,1000,opt,name=ConfigClientMachineBenchmarkOptions" json:"ConfigClientMachineBenchmarkOptions,omitempty" yaml:"benchmark_options"` ConfigClientMachineBenchmarkOptions *ConfigClientMachineBenchmarkOptions `protobuf:"bytes,1000,opt,name=ConfigClientMachineBenchmarkOptions" json:"ConfigClientMachineBenchmarkOptions,omitempty" yaml:"benchmark_options"`
@ -479,125 +474,65 @@ func (m *ConfigClientMachineAgentControl) MarshalTo(dAtA []byte) (int, error) {
i += copy(dAtA[i:], s) i += copy(dAtA[i:], s)
} }
} }
if m.Flag_Etcd_V2_3 != nil { if m.Flag_Etcd_Tip != nil {
dAtA[i] = 0xa2 dAtA[i] = 0xa2
i++ i++
dAtA[i] = 0x6 dAtA[i] = 0x6
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Etcd_V2_3.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Etcd_Tip.Size()))
n3, err := m.Flag_Etcd_V2_3.MarshalTo(dAtA[i:]) n3, err := m.Flag_Etcd_Tip.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n3 i += n3
} }
if m.Flag_Etcd_V3_1 != nil { if m.Flag_Etcd_V3_2 != nil {
dAtA[i] = 0xaa dAtA[i] = 0xaa
i++ i++
dAtA[i] = 0x6 dAtA[i] = 0x6
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Etcd_V3_1.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Etcd_V3_2.Size()))
n4, err := m.Flag_Etcd_V3_1.MarshalTo(dAtA[i:]) n4, err := m.Flag_Etcd_V3_2.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n4 i += n4
} }
if m.Flag_Etcd_V3_2 != nil { if m.Flag_Etcd_V3_3 != nil {
dAtA[i] = 0xb2 dAtA[i] = 0xb2
i++ i++
dAtA[i] = 0x6 dAtA[i] = 0x6
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Etcd_V3_2.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Etcd_V3_3.Size()))
n5, err := m.Flag_Etcd_V3_2.MarshalTo(dAtA[i:]) n5, err := m.Flag_Etcd_V3_3.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n5 i += n5
} }
if m.Flag_Etcd_Tip != nil { if m.Flag_Zookeeper_R3_5_3Beta != nil {
dAtA[i] = 0xba dAtA[i] = 0xc2
i++ i++
dAtA[i] = 0x6 dAtA[i] = 0xc
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Etcd_Tip.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Zookeeper_R3_5_3Beta.Size()))
n6, err := m.Flag_Etcd_Tip.MarshalTo(dAtA[i:]) n6, err := m.Flag_Zookeeper_R3_5_3Beta.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n6 i += n6
} }
if m.Flag_Zookeeper_R3_4_9 != nil { if m.Flag_Consul_V1_0_2 != nil {
dAtA[i] = 0xc2
i++
dAtA[i] = 0xc
i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Zookeeper_R3_4_9.Size()))
n7, err := m.Flag_Zookeeper_R3_4_9.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n7
}
if m.Flag_Zookeeper_R3_5_2Alpha != nil {
dAtA[i] = 0xca
i++
dAtA[i] = 0xc
i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Zookeeper_R3_5_2Alpha.Size()))
n8, err := m.Flag_Zookeeper_R3_5_2Alpha.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n8
}
if m.Flag_Zookeeper_R3_5_3Beta != nil {
dAtA[i] = 0xd2
i++
dAtA[i] = 0xc
i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Zookeeper_R3_5_3Beta.Size()))
n9, err := m.Flag_Zookeeper_R3_5_3Beta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n9
}
if m.Flag_Consul_V0_7_5 != nil {
dAtA[i] = 0xe2 dAtA[i] = 0xe2
i++ i++
dAtA[i] = 0x12 dAtA[i] = 0x12
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Consul_V0_7_5.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Consul_V1_0_2.Size()))
n10, err := m.Flag_Consul_V0_7_5.MarshalTo(dAtA[i:]) n7, err := m.Flag_Consul_V1_0_2.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n10 i += n7
}
if m.Flag_Consul_V0_8_0 != nil {
dAtA[i] = 0xea
i++
dAtA[i] = 0x12
i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Consul_V0_8_0.Size()))
n11, err := m.Flag_Consul_V0_8_0.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n11
}
if m.Flag_Consul_V0_8_4 != nil {
dAtA[i] = 0xf2
i++
dAtA[i] = 0x12
i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Consul_V0_8_4.Size()))
n12, err := m.Flag_Consul_V0_8_4.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n12
} }
if m.Flag_Cetcd_Beta != nil { if m.Flag_Cetcd_Beta != nil {
dAtA[i] = 0x82 dAtA[i] = 0x82
@ -605,11 +540,11 @@ func (m *ConfigClientMachineAgentControl) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x19 dAtA[i] = 0x19
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Cetcd_Beta.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Cetcd_Beta.Size()))
n13, err := m.Flag_Cetcd_Beta.MarshalTo(dAtA[i:]) n8, err := m.Flag_Cetcd_Beta.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n13 i += n8
} }
if m.Flag_Zetcd_Beta != nil { if m.Flag_Zetcd_Beta != nil {
dAtA[i] = 0xa2 dAtA[i] = 0xa2
@ -617,11 +552,11 @@ func (m *ConfigClientMachineAgentControl) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x1f dAtA[i] = 0x1f
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Zetcd_Beta.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.Flag_Zetcd_Beta.Size()))
n14, err := m.Flag_Zetcd_Beta.MarshalTo(dAtA[i:]) n9, err := m.Flag_Zetcd_Beta.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n14 i += n9
} }
if m.ConfigClientMachineBenchmarkOptions != nil { if m.ConfigClientMachineBenchmarkOptions != nil {
dAtA[i] = 0xc2 dAtA[i] = 0xc2
@ -629,11 +564,11 @@ func (m *ConfigClientMachineAgentControl) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x3e dAtA[i] = 0x3e
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.ConfigClientMachineBenchmarkOptions.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.ConfigClientMachineBenchmarkOptions.Size()))
n15, err := m.ConfigClientMachineBenchmarkOptions.MarshalTo(dAtA[i:]) n10, err := m.ConfigClientMachineBenchmarkOptions.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n15 i += n10
} }
if m.ConfigClientMachineBenchmarkSteps != nil { if m.ConfigClientMachineBenchmarkSteps != nil {
dAtA[i] = 0xca dAtA[i] = 0xca
@ -641,33 +576,15 @@ func (m *ConfigClientMachineAgentControl) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x3e dAtA[i] = 0x3e
i++ i++
i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.ConfigClientMachineBenchmarkSteps.Size())) i = encodeVarintConfigClientMachine(dAtA, i, uint64(m.ConfigClientMachineBenchmarkSteps.Size()))
n16, err := m.ConfigClientMachineBenchmarkSteps.MarshalTo(dAtA[i:]) n11, err := m.ConfigClientMachineBenchmarkSteps.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n16 i += n11
} }
return i, nil return i, nil
} }
func encodeFixed64ConfigClientMachine(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32ConfigClientMachine(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintConfigClientMachine(dAtA []byte, offset int, v uint64) int { func encodeVarintConfigClientMachine(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)
@ -845,44 +762,24 @@ func (m *ConfigClientMachineAgentControl) Size() (n int) {
n += 1 + l + sovConfigClientMachine(uint64(l)) n += 1 + l + sovConfigClientMachine(uint64(l))
} }
} }
if m.Flag_Etcd_V2_3 != nil { if m.Flag_Etcd_Tip != nil {
l = m.Flag_Etcd_V2_3.Size() l = m.Flag_Etcd_Tip.Size()
n += 2 + l + sovConfigClientMachine(uint64(l))
}
if m.Flag_Etcd_V3_1 != nil {
l = m.Flag_Etcd_V3_1.Size()
n += 2 + l + sovConfigClientMachine(uint64(l)) n += 2 + l + sovConfigClientMachine(uint64(l))
} }
if m.Flag_Etcd_V3_2 != nil { if m.Flag_Etcd_V3_2 != nil {
l = m.Flag_Etcd_V3_2.Size() l = m.Flag_Etcd_V3_2.Size()
n += 2 + l + sovConfigClientMachine(uint64(l)) n += 2 + l + sovConfigClientMachine(uint64(l))
} }
if m.Flag_Etcd_Tip != nil { if m.Flag_Etcd_V3_3 != nil {
l = m.Flag_Etcd_Tip.Size() l = m.Flag_Etcd_V3_3.Size()
n += 2 + l + sovConfigClientMachine(uint64(l))
}
if m.Flag_Zookeeper_R3_4_9 != nil {
l = m.Flag_Zookeeper_R3_4_9.Size()
n += 2 + l + sovConfigClientMachine(uint64(l))
}
if m.Flag_Zookeeper_R3_5_2Alpha != nil {
l = m.Flag_Zookeeper_R3_5_2Alpha.Size()
n += 2 + l + sovConfigClientMachine(uint64(l)) n += 2 + l + sovConfigClientMachine(uint64(l))
} }
if m.Flag_Zookeeper_R3_5_3Beta != nil { if m.Flag_Zookeeper_R3_5_3Beta != nil {
l = m.Flag_Zookeeper_R3_5_3Beta.Size() l = m.Flag_Zookeeper_R3_5_3Beta.Size()
n += 2 + l + sovConfigClientMachine(uint64(l)) n += 2 + l + sovConfigClientMachine(uint64(l))
} }
if m.Flag_Consul_V0_7_5 != nil { if m.Flag_Consul_V1_0_2 != nil {
l = m.Flag_Consul_V0_7_5.Size() l = m.Flag_Consul_V1_0_2.Size()
n += 2 + l + sovConfigClientMachine(uint64(l))
}
if m.Flag_Consul_V0_8_0 != nil {
l = m.Flag_Consul_V0_8_0.Size()
n += 2 + l + sovConfigClientMachine(uint64(l))
}
if m.Flag_Consul_V0_8_4 != nil {
l = m.Flag_Consul_V0_8_4.Size()
n += 2 + l + sovConfigClientMachine(uint64(l)) n += 2 + l + sovConfigClientMachine(uint64(l))
} }
if m.Flag_Cetcd_Beta != nil { if m.Flag_Cetcd_Beta != nil {
@ -2099,7 +1996,7 @@ func (m *ConfigClientMachineAgentControl) Unmarshal(dAtA []byte) error {
iNdEx = postIndex iNdEx = postIndex
case 100: case 100:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V2_3", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_Tip", wireType)
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -2123,47 +2020,14 @@ func (m *ConfigClientMachineAgentControl) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if m.Flag_Etcd_V2_3 == nil { if m.Flag_Etcd_Tip == nil {
m.Flag_Etcd_V2_3 = &Flag_Etcd_V2_3{} m.Flag_Etcd_Tip = &Flag_Etcd_Tip{}
} }
if err := m.Flag_Etcd_V2_3.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Flag_Etcd_Tip.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 101: case 101:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V3_1", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfigClientMachine
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfigClientMachine
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Etcd_V3_1 == nil {
m.Flag_Etcd_V3_1 = &Flag_Etcd_V3_1{}
}
if err := m.Flag_Etcd_V3_1.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 102:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V3_2", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V3_2", wireType)
} }
@ -2196,9 +2060,9 @@ func (m *ConfigClientMachineAgentControl) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 103: case 102:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_Tip", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V3_3", wireType)
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -2222,80 +2086,14 @@ func (m *ConfigClientMachineAgentControl) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if m.Flag_Etcd_Tip == nil { if m.Flag_Etcd_V3_3 == nil {
m.Flag_Etcd_Tip = &Flag_Etcd_Tip{} m.Flag_Etcd_V3_3 = &Flag_Etcd_V3_3{}
} }
if err := m.Flag_Etcd_Tip.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Flag_Etcd_V3_3.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 200: case 200:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Zookeeper_R3_4_9", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfigClientMachine
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfigClientMachine
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Zookeeper_R3_4_9 == nil {
m.Flag_Zookeeper_R3_4_9 = &Flag_Zookeeper_R3_4_9{}
}
if err := m.Flag_Zookeeper_R3_4_9.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 201:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Zookeeper_R3_5_2Alpha", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfigClientMachine
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfigClientMachine
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Zookeeper_R3_5_2Alpha == nil {
m.Flag_Zookeeper_R3_5_2Alpha = &Flag_Zookeeper_R3_5_2Alpha{}
}
if err := m.Flag_Zookeeper_R3_5_2Alpha.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 202:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Zookeeper_R3_5_3Beta", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Zookeeper_R3_5_3Beta", wireType)
} }
@ -2330,7 +2128,7 @@ func (m *ConfigClientMachineAgentControl) Unmarshal(dAtA []byte) error {
iNdEx = postIndex iNdEx = postIndex
case 300: case 300:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Consul_V0_7_5", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Consul_V1_0_2", wireType)
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -2354,76 +2152,10 @@ func (m *ConfigClientMachineAgentControl) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if m.Flag_Consul_V0_7_5 == nil { if m.Flag_Consul_V1_0_2 == nil {
m.Flag_Consul_V0_7_5 = &Flag_Consul_V0_7_5{} m.Flag_Consul_V1_0_2 = &Flag_Consul_V1_0_2{}
} }
if err := m.Flag_Consul_V0_7_5.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Flag_Consul_V1_0_2.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 301:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Consul_V0_8_0", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfigClientMachine
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfigClientMachine
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Consul_V0_8_0 == nil {
m.Flag_Consul_V0_8_0 = &Flag_Consul_V0_8_0{}
}
if err := m.Flag_Consul_V0_8_0.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 302:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Consul_V0_8_4", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfigClientMachine
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfigClientMachine
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Consul_V0_8_4 == nil {
m.Flag_Consul_V0_8_4 = &Flag_Consul_V0_8_4{}
}
if err := m.Flag_Consul_V0_8_4.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
@ -2690,119 +2422,111 @@ func init() {
} }
var fileDescriptorConfigClientMachine = []byte{ var fileDescriptorConfigClientMachine = []byte{
// 1811 bytes of a gzipped FileDescriptorProto // 1684 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x58, 0x6d, 0x6f, 0x1b, 0x49, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x58, 0x4f, 0x73, 0xdb, 0xc6,
0x1d, 0x3f, 0x37, 0xed, 0x35, 0x99, 0xf4, 0x29, 0xd3, 0xa6, 0x71, 0xd3, 0x34, 0x93, 0x6e, 0x5a, 0x15, 0x0f, 0x4d, 0x3b, 0x96, 0x56, 0xfe, 0xbb, 0xb6, 0x6c, 0x5a, 0x96, 0xb5, 0x32, 0x6c, 0x37,
0x2e, 0xd5, 0xd1, 0x3c, 0xd8, 0xee, 0x5d, 0x8b, 0x40, 0x50, 0x27, 0x07, 0x54, 0xcd, 0xdd, 0x99, 0xca, 0xa4, 0x96, 0x6c, 0xd2, 0xc9, 0x4c, 0x3b, 0xed, 0xb4, 0xa1, 0x94, 0xb6, 0x1e, 0x2b, 0x09,
0x75, 0xae, 0x88, 0x0a, 0x31, 0x8c, 0xd7, 0x93, 0xf5, 0x5e, 0xd6, 0x3b, 0xcb, 0xce, 0x38, 0xc2, 0x0b, 0x2a, 0xee, 0xd4, 0xd3, 0xe9, 0x76, 0x09, 0x3e, 0x41, 0x88, 0x40, 0x2c, 0x8a, 0x5d, 0x78,
0xe1, 0x2d, 0x12, 0x02, 0x09, 0xe9, 0x5e, 0xde, 0x4b, 0x3e, 0x00, 0xf0, 0x31, 0x50, 0xe1, 0x15, 0x4a, 0xf5, 0xda, 0x99, 0x4e, 0x7b, 0xca, 0x31, 0xc7, 0xf6, 0xde, 0xcf, 0xd1, 0xf1, 0xb1, 0x9f,
0x5f, 0x80, 0x15, 0xb4, 0x6f, 0xe0, 0xed, 0x8a, 0x0f, 0x70, 0x9a, 0xff, 0xac, 0xed, 0xb5, 0xbd, 0x00, 0xd3, 0xda, 0x97, 0xf6, 0x8a, 0xe9, 0x07, 0xc8, 0xec, 0x03, 0x48, 0x02, 0x24, 0x44, 0xf1,
0x76, 0xfc, 0xce, 0x3b, 0xff, 0xdf, 0xd3, 0xcc, 0xce, 0xd3, 0x1a, 0x7d, 0xab, 0xd9, 0x50, 0x5c, 0x26, 0xee, 0xfb, 0xfd, 0xdb, 0x05, 0xf6, 0xed, 0x42, 0xe4, 0x7b, 0xfd, 0x9e, 0x06, 0xa5, 0x21,
0x2a, 0x1e, 0x85, 0x8d, 0x1d, 0x47, 0x04, 0xc7, 0x9e, 0x4b, 0x1d, 0xdf, 0xe3, 0x81, 0xa2, 0x6d, 0x0a, 0x7b, 0x3b, 0x8e, 0x0c, 0x0e, 0x3d, 0x97, 0x3b, 0xbe, 0x07, 0x81, 0xe6, 0x03, 0xe1, 0x1c,
0xe6, 0xb4, 0xbc, 0x80, 0x6f, 0x87, 0x91, 0x50, 0x02, 0xa3, 0x01, 0x6e, 0xf5, 0xb1, 0xeb, 0xa9, 0x79, 0x01, 0x6c, 0x87, 0x91, 0xd4, 0x92, 0x92, 0x09, 0x6e, 0xed, 0xb1, 0xeb, 0xe9, 0xa3, 0xb8,
0x56, 0xa7, 0xb1, 0xed, 0x88, 0xf6, 0x8e, 0x2b, 0x5c, 0xb1, 0x03, 0x90, 0x46, 0xe7, 0x18, 0x9e, 0xb7, 0xed, 0xc8, 0xc1, 0x8e, 0x2b, 0x5d, 0xb9, 0x83, 0x90, 0x5e, 0x7c, 0x88, 0xbf, 0xf0, 0x07,
0xe0, 0x01, 0x7e, 0x19, 0xea, 0xea, 0x6a, 0xc6, 0xe2, 0xd8, 0x67, 0x2e, 0xe5, 0xca, 0x69, 0xa6, 0xfe, 0x95, 0x51, 0xd7, 0xd6, 0x0a, 0x16, 0x87, 0xbe, 0x70, 0x39, 0x68, 0xa7, 0x9f, 0xd7, 0xd8,
0x35, 0x32, 0x5a, 0x3b, 0x13, 0xe2, 0x84, 0xf3, 0x90, 0x47, 0x29, 0x60, 0x6d, 0x14, 0xe0, 0x88, 0x74, 0xed, 0x44, 0xca, 0x63, 0x80, 0x10, 0xa2, 0x1c, 0xb0, 0x3e, 0x0d, 0x70, 0x64, 0xa0, 0x62,
0x40, 0x76, 0xfc, 0xb4, 0x7a, 0x77, 0x8c, 0x9e, 0xd1, 0x1e, 0x2b, 0x3a, 0x83, 0xa2, 0xf5, 0xee, 0x3f, 0xaf, 0xde, 0x9d, 0xa1, 0x17, 0xb4, 0x67, 0x8a, 0xce, 0xa4, 0x68, 0xbd, 0xbb, 0x44, 0xd6,
0x0a, 0x5a, 0xdd, 0x87, 0xfe, 0xee, 0x43, 0x77, 0x3f, 0x35, 0xbd, 0x7d, 0x11, 0x78, 0xca, 0x63, 0x76, 0x71, 0xbe, 0xbb, 0x38, 0xdd, 0xcf, 0xb3, 0xd9, 0x3e, 0x0f, 0x3c, 0xed, 0x09, 0x9f, 0x7e,
0x3e, 0xfe, 0x08, 0xa1, 0x1a, 0x53, 0xad, 0x5a, 0xc4, 0x8f, 0xbd, 0x5f, 0x17, 0x0b, 0x1b, 0x85, 0x42, 0x48, 0x47, 0xe8, 0xa3, 0x4e, 0x04, 0x87, 0xde, 0x1f, 0x1a, 0xb5, 0xcd, 0xda, 0xd6, 0x72,
0xad, 0x85, 0xea, 0xed, 0x24, 0x26, 0xb8, 0xcb, 0xda, 0xfe, 0x77, 0xac, 0x90, 0xa9, 0x16, 0x0d, 0xfb, 0x56, 0x9a, 0x30, 0x3a, 0x14, 0x03, 0xff, 0x87, 0x56, 0x28, 0xf4, 0x11, 0x0f, 0xb1, 0x68,
0xa1, 0x68, 0xd9, 0x19, 0x24, 0x7e, 0x8c, 0x2e, 0x1f, 0x0a, 0x57, 0x37, 0x14, 0x2f, 0x00, 0xe9, 0xd9, 0x05, 0x24, 0x7d, 0x4c, 0x2e, 0xee, 0x4b, 0xd7, 0x0c, 0x34, 0xce, 0x21, 0xe9, 0x46, 0x9a,
0x66, 0x12, 0x93, 0xeb, 0x86, 0xe4, 0x0b, 0x97, 0x6a, 0xa2, 0x65, 0xf7, 0x30, 0x98, 0xa2, 0x15, 0xb0, 0xab, 0x19, 0xc9, 0x97, 0x2e, 0x37, 0x44, 0xcb, 0x1e, 0x61, 0x28, 0x27, 0xb7, 0x33, 0xfb,
0x63, 0x5f, 0xef, 0x4a, 0xc5, 0xdb, 0x9f, 0x72, 0x15, 0x79, 0x8e, 0x04, 0xfa, 0x1c, 0xd0, 0x1f, 0xee, 0x50, 0x69, 0x18, 0x7c, 0x0e, 0x3a, 0xf2, 0x1c, 0x85, 0xf4, 0x3a, 0xd2, 0x1f, 0xa5, 0x09,
0x26, 0x31, 0xb9, 0x6f, 0xe8, 0xe9, 0x6b, 0x91, 0x80, 0xa4, 0x6d, 0x03, 0x4d, 0x05, 0x27, 0xa9, 0xbb, 0x9f, 0xd1, 0xf3, 0xc7, 0xa2, 0x10, 0xc9, 0x07, 0x19, 0x34, 0x17, 0x3c, 0x4d, 0x85, 0xfe,
0xe0, 0xdf, 0x16, 0xd0, 0x66, 0x4e, 0xed, 0x45, 0xa0, 0x87, 0x45, 0xf8, 0x4c, 0xf1, 0x26, 0xb8, 0xa9, 0x46, 0x1e, 0x54, 0xd4, 0x9e, 0x07, 0x66, 0x59, 0xa4, 0x2f, 0x34, 0xf4, 0xd1, 0xed, 0x3c,
0x5d, 0x04, 0xb7, 0x52, 0x12, 0x93, 0xed, 0x69, 0x6e, 0x5e, 0x86, 0x97, 0x5a, 0xcf, 0x22, 0x8f, 0xba, 0x35, 0xd3, 0x84, 0x6d, 0xcf, 0x73, 0xf3, 0x0a, 0xbc, 0xdc, 0x7a, 0x11, 0x79, 0xfa, 0xd7,
0xff, 0x50, 0x40, 0x0f, 0x0d, 0xee, 0x90, 0x29, 0x1e, 0x38, 0xdd, 0xa3, 0x56, 0x24, 0x3a, 0x6e, 0x1a, 0x79, 0x94, 0xe1, 0xf6, 0x85, 0x86, 0xc0, 0x19, 0x1e, 0x1c, 0x45, 0x32, 0x76, 0x8f, 0xc2,
0x2b, 0xec, 0xa8, 0x23, 0xaf, 0xcd, 0x25, 0x8f, 0x3c, 0x6e, 0xba, 0x7d, 0x09, 0x82, 0x54, 0x92, 0x58, 0x1f, 0x78, 0x03, 0x50, 0x10, 0x79, 0x90, 0x4d, 0xfb, 0x02, 0x06, 0x79, 0x96, 0x26, 0xec,
0x98, 0xec, 0x0e, 0x05, 0xf1, 0x0d, 0x8f, 0xaa, 0x3e, 0x91, 0xaa, 0x3e, 0x33, 0x8d, 0x32, 0x9b, 0x49, 0x29, 0x88, 0x9f, 0xf1, 0xb8, 0x1e, 0x13, 0xb9, 0x1e, 0x33, 0xf3, 0x28, 0x8b, 0x59, 0xd0,
0x05, 0xfe, 0x0d, 0xda, 0x18, 0x02, 0x1e, 0x78, 0x52, 0x45, 0x5e, 0xa3, 0xa3, 0x3c, 0x11, 0x3c, 0x3f, 0x92, 0xcd, 0x12, 0x70, 0xcf, 0x53, 0x3a, 0xf2, 0x7a, 0xb1, 0xf6, 0x64, 0xf0, 0xa9, 0xef,
0xf7, 0x7d, 0x88, 0xf1, 0x3e, 0xc4, 0xd8, 0x49, 0x62, 0xf2, 0x61, 0x6e, 0x8c, 0x66, 0x86, 0x43, 0x63, 0x8c, 0xf7, 0x31, 0xc6, 0x4e, 0x9a, 0xb0, 0x8f, 0x2a, 0x63, 0xf4, 0x0b, 0x1c, 0x2e, 0x7c,
0x99, 0xef, 0xa7, 0x09, 0xce, 0x15, 0xc6, 0x5f, 0x15, 0xd0, 0x07, 0x13, 0x41, 0x35, 0x1e, 0x39, 0x3f, 0x4f, 0x70, 0xa6, 0x30, 0xfd, 0xa6, 0x46, 0x3e, 0x38, 0x15, 0xd4, 0x81, 0xc8, 0x81, 0x40,
0x3c, 0x50, 0x9e, 0xcf, 0x21, 0xc4, 0x65, 0x08, 0xf1, 0x51, 0x12, 0x93, 0xd2, 0xf9, 0x21, 0xc2, 0x7b, 0x3e, 0x60, 0x88, 0x8b, 0x18, 0xe2, 0x93, 0x34, 0x61, 0xcd, 0xb3, 0x43, 0x84, 0x63, 0x6e,
0x3e, 0x37, 0xcd, 0x32, 0xab, 0x0d, 0xfe, 0x5d, 0x01, 0x3d, 0x98, 0x88, 0xad, 0x77, 0xda, 0x6d, 0x9e, 0x65, 0x51, 0x1b, 0xfa, 0xe7, 0x1a, 0x79, 0x78, 0x2a, 0xb6, 0x1b, 0x0f, 0x06, 0x22, 0x1a,
0x16, 0x75, 0x21, 0xcf, 0x3c, 0xe4, 0x29, 0x27, 0x31, 0xd9, 0x39, 0x3f, 0x8f, 0x34, 0xc4, 0x34, 0x62, 0x9e, 0x25, 0xcc, 0xd3, 0x4a, 0x13, 0xb6, 0x73, 0x76, 0x1e, 0x95, 0x11, 0xf3, 0x30, 0x0b,
0xcc, 0x4c, 0x06, 0x38, 0x44, 0x6b, 0x43, 0xb8, 0x6a, 0xf7, 0x25, 0xef, 0x7e, 0xd6, 0x69, 0x37, 0x19, 0xd0, 0x90, 0xac, 0x97, 0x70, 0xed, 0xe1, 0x0b, 0x18, 0x7e, 0x11, 0x0f, 0x7a, 0x10, 0x61,
0x78, 0x04, 0x01, 0x16, 0x20, 0xc0, 0xb7, 0x93, 0x98, 0x6c, 0xe5, 0x06, 0x68, 0x74, 0xe9, 0x09, 0x80, 0x65, 0x0c, 0xf0, 0xfd, 0x34, 0x61, 0x5b, 0x95, 0x01, 0x7a, 0x43, 0x7e, 0x0c, 0x43, 0x1e,
0xef, 0xd2, 0x00, 0x18, 0xa9, 0xf3, 0x54, 0x45, 0xdc, 0x45, 0xa4, 0xce, 0xa3, 0x53, 0x1e, 0x1d, 0x20, 0x23, 0x77, 0x9e, 0xab, 0x48, 0x87, 0x84, 0x75, 0x21, 0x7a, 0x0d, 0xd1, 0x9e, 0xa7, 0x8e,
0x78, 0xf2, 0xa4, 0x1e, 0x32, 0x87, 0x7f, 0x21, 0x99, 0xcb, 0xb3, 0xbd, 0x46, 0xa3, 0x53, 0x41, 0xbb, 0xa1, 0x70, 0xe0, 0x2b, 0x25, 0x5c, 0x28, 0xce, 0x9a, 0x4c, 0xbf, 0x0a, 0x0a, 0x09, 0x66,
0x02, 0x41, 0xf7, 0xf6, 0x84, 0x4a, 0x4d, 0xa1, 0x1d, 0xcd, 0x19, 0xe9, 0xf1, 0x79, 0xba, 0xf8, 0xb6, 0xc7, 0x5c, 0x19, 0x0a, 0x8f, 0x0d, 0x67, 0x6a, 0xc6, 0x67, 0xe9, 0xd2, 0xdf, 0x90, 0x5b,
0xe7, 0xe8, 0xf6, 0x8f, 0x84, 0x70, 0x7d, 0xbe, 0xef, 0x8b, 0x4e, 0xb3, 0x16, 0x89, 0x2f, 0xb9, 0x3f, 0x97, 0xd2, 0xf5, 0x61, 0xd7, 0x97, 0x71, 0xbf, 0x13, 0xc9, 0xaf, 0xc1, 0xd1, 0x5f, 0x88,
0xa3, 0x3e, 0x63, 0x6d, 0x5e, 0x6c, 0x82, 0xe3, 0x83, 0x24, 0x26, 0x1b, 0xc6, 0xd1, 0x05, 0x1c, 0x01, 0x34, 0xfa, 0xe8, 0xf8, 0x30, 0x4d, 0xd8, 0x66, 0xe6, 0xe8, 0x22, 0x8e, 0x3b, 0x06, 0xc8,
0x75, 0x34, 0x90, 0x86, 0x06, 0x49, 0x03, 0xd6, 0xe6, 0x96, 0x3d, 0x41, 0x03, 0x1f, 0xa3, 0x3b, 0xc3, 0x0c, 0xc9, 0x03, 0x31, 0x00, 0xcb, 0x3e, 0x45, 0x83, 0x1e, 0x92, 0x3b, 0x85, 0x4a, 0x57,
0x99, 0x4a, 0x5d, 0x89, 0x88, 0xb9, 0xfc, 0x25, 0x37, 0x5d, 0xe2, 0x60, 0xb0, 0x95, 0xc4, 0xe4, 0xcb, 0x48, 0xb8, 0xf0, 0x02, 0xb2, 0x29, 0x01, 0x1a, 0x6c, 0xa5, 0x09, 0x7b, 0x58, 0x61, 0xa0,
0x41, 0x8e, 0x81, 0x34, 0x60, 0x18, 0x4a, 0xd3, 0x97, 0xc9, 0x52, 0xb8, 0x82, 0x96, 0x73, 0x8b, 0x32, 0x30, 0x2e, 0x65, 0x36, 0x97, 0xd3, 0xa5, 0xe8, 0x33, 0xb2, 0x5a, 0x59, 0x6c, 0x1c, 0x1a,
0xc5, 0x63, 0xed, 0x61, 0xe7, 0x17, 0xb1, 0x40, 0x6b, 0xe3, 0x85, 0x6a, 0xc7, 0x39, 0xe1, 0x66, 0x0f, 0xbb, 0xba, 0x48, 0x25, 0x59, 0x9f, 0x2d, 0xb4, 0x63, 0xe7, 0x18, 0xb2, 0x15, 0x70, 0x31,
0x04, 0x5c, 0x08, 0xf8, 0x61, 0x12, 0x93, 0x0f, 0xa6, 0x04, 0x6c, 0x00, 0x21, 0x1d, 0x88, 0xa9, 0xe0, 0x47, 0x69, 0xc2, 0x3e, 0x98, 0x13, 0xb0, 0x87, 0x84, 0x7c, 0x21, 0xe6, 0x0a, 0xd2, 0x98,
0x82, 0xb8, 0x83, 0xd6, 0xc7, 0xeb, 0xf5, 0x4e, 0xe3, 0xc0, 0x8b, 0xb8, 0xa3, 0x44, 0xd4, 0x2d, 0x6c, 0xcc, 0xd6, 0xbb, 0x71, 0x6f, 0xcf, 0x8b, 0xc0, 0xd1, 0x32, 0x1a, 0x36, 0x8e, 0xd0, 0xf2,
0xb6, 0xc0, 0xf2, 0x71, 0x12, 0x93, 0x47, 0x53, 0x2c, 0x65, 0xa7, 0x41, 0x9b, 0x3d, 0x8e, 0x65, 0x71, 0x9a, 0xb0, 0x0f, 0xe7, 0x58, 0xaa, 0xb8, 0xc7, 0xfb, 0x23, 0x8e, 0x65, 0x9f, 0x21, 0x6a,
0x9f, 0x23, 0x6a, 0xfd, 0xed, 0x12, 0xda, 0xcc, 0x39, 0x65, 0xaa, 0x3c, 0x70, 0x5a, 0x6d, 0x16, 0xfd, 0xf3, 0x02, 0x79, 0x50, 0x71, 0xca, 0xb4, 0x21, 0x70, 0x8e, 0x06, 0x22, 0x3a, 0xfe, 0x32,
0x9d, 0x7c, 0x1e, 0xea, 0x25, 0x20, 0xf1, 0x26, 0xba, 0x78, 0xd4, 0x0d, 0x79, 0x7a, 0xd0, 0x5c, 0x34, 0x5b, 0x40, 0xd1, 0x07, 0xe4, 0xfc, 0xc1, 0x30, 0x84, 0xfc, 0xa0, 0xb9, 0x9a, 0x26, 0x6c,
0x4f, 0x62, 0xb2, 0x68, 0x42, 0xa8, 0x6e, 0xc8, 0x2d, 0x1b, 0x8a, 0xf8, 0xfb, 0xe8, 0xaa, 0xcd, 0x25, 0x0b, 0xa1, 0x87, 0x21, 0x58, 0x36, 0x16, 0xe9, 0x4f, 0xc8, 0x65, 0x1b, 0x7e, 0x1f, 0x83,
0x7f, 0xd5, 0xe1, 0x52, 0x99, 0x09, 0x0c, 0x27, 0xcc, 0x5c, 0xf5, 0x4e, 0x12, 0x93, 0x65, 0x83, 0xd2, 0xd9, 0x0b, 0x8c, 0x27, 0x4c, 0xbd, 0x7d, 0x27, 0x4d, 0xd8, 0x6a, 0x86, 0x8e, 0xb2, 0x72,
0x8e, 0x4c, 0x39, 0x5d, 0x00, 0x96, 0x3d, 0x8c, 0xc7, 0x3f, 0x46, 0x37, 0xf6, 0x45, 0x10, 0x70, 0xbe, 0x01, 0x2c, 0xbb, 0x8c, 0xa7, 0xbf, 0x20, 0xd7, 0x76, 0x65, 0x10, 0x80, 0x63, 0x4c, 0x73,
0x47, 0x9b, 0xa6, 0x1a, 0x73, 0xa0, 0xb1, 0x96, 0xc4, 0xa4, 0x98, 0x2e, 0xa9, 0x3e, 0xa2, 0x2f, 0x8d, 0x3a, 0x6a, 0xac, 0xa7, 0x09, 0x6b, 0xe4, 0x5b, 0x6a, 0x8c, 0x18, 0xcb, 0xcc, 0xb0, 0xe8,
0x33, 0xc6, 0xc2, 0xdf, 0x45, 0x57, 0x4c, 0x87, 0x52, 0x95, 0x8b, 0xa0, 0x52, 0x4c, 0x62, 0x72, 0x8f, 0xc8, 0xa5, 0x6c, 0x42, 0xb9, 0xca, 0x79, 0x54, 0x69, 0xa4, 0x09, 0xbb, 0x59, 0xda, 0x98,
0x6b, 0x68, 0x61, 0xf6, 0x14, 0x86, 0xd0, 0xf8, 0x17, 0x68, 0x65, 0xa0, 0x98, 0xad, 0xc8, 0xe2, 0x23, 0x85, 0x12, 0x9a, 0xfe, 0x96, 0xdc, 0x9e, 0x28, 0x16, 0x2b, 0xaa, 0x71, 0x61, 0xb3, 0xbe,
0xa5, 0x8d, 0xb9, 0xad, 0xb9, 0xec, 0xd4, 0xcf, 0xc4, 0x19, 0xd2, 0x94, 0xfa, 0xd0, 0xcb, 0x17, 0x55, 0x2f, 0xbe, 0xfa, 0x85, 0x38, 0x25, 0x4d, 0x65, 0x0e, 0xbd, 0x6a, 0x11, 0xea, 0x91, 0x35,
0xc1, 0x1e, 0x5a, 0xb5, 0x99, 0xe2, 0x87, 0x5e, 0xdb, 0x53, 0xe9, 0x08, 0xc8, 0x1a, 0x8f, 0xea, 0x5b, 0x68, 0xd8, 0xf7, 0x06, 0x9e, 0xce, 0x57, 0x40, 0x75, 0x20, 0xea, 0x82, 0x23, 0x83, 0x3e,
0xdc, 0x11, 0x41, 0x13, 0xb6, 0xf6, 0xb9, 0xea, 0xa3, 0x24, 0x26, 0x0f, 0xd3, 0x51, 0x63, 0x8a, 0xb6, 0xf6, 0x7a, 0xfb, 0xc3, 0x34, 0x61, 0x8f, 0xf2, 0x55, 0x13, 0x1a, 0xb8, 0x6f, 0xc0, 0x3c,
0x53, 0x5f, 0x83, 0x69, 0x3a, 0x80, 0x52, 0xef, 0xa6, 0x54, 0x02, 0xde, 0xb2, 0xa7, 0x88, 0xe9, 0x5f, 0x40, 0x65, 0xba, 0x29, 0x57, 0x88, 0xb7, 0xec, 0x39, 0x62, 0xe6, 0xbc, 0xef, 0x8a, 0x01,
0xf3, 0xbe, 0xce, 0xda, 0x30, 0xe1, 0xf5, 0x6e, 0x3d, 0x9f, 0x3d, 0xef, 0x25, 0x6b, 0xc3, 0x22, 0xbe, 0xf0, 0xa6, 0x5b, 0x2f, 0x15, 0xcf, 0x7b, 0x25, 0x06, 0xb8, 0x89, 0x2c, 0x7b, 0x84, 0xa1,
0xb2, 0xec, 0x1e, 0x06, 0x7f, 0x0f, 0x5d, 0x79, 0xc9, 0xbb, 0x75, 0xef, 0x8c, 0x57, 0xbb, 0x8a, 0x3f, 0x26, 0x97, 0x5e, 0xc0, 0xb0, 0xeb, 0x9d, 0x40, 0x7b, 0xa8, 0x41, 0x61, 0x47, 0x2d, 0x3d,
0x4b, 0xd8, 0x51, 0x87, 0xde, 0xa0, 0x5e, 0x73, 0xd2, 0x3b, 0xe3, 0xb4, 0xa1, 0xeb, 0x96, 0x3d, 0x41, 0xb3, 0xe7, 0x94, 0x77, 0x02, 0xbc, 0x67, 0xea, 0x96, 0x5d, 0x82, 0xd3, 0x5d, 0x72, 0xe5,
0x04, 0xc7, 0xfb, 0xe8, 0xda, 0x2b, 0xe6, 0x77, 0xf8, 0x40, 0x60, 0x01, 0x04, 0xee, 0x26, 0x31, 0xa5, 0xf0, 0x63, 0x98, 0x08, 0x2c, 0xa3, 0xc0, 0xdd, 0x34, 0x61, 0xb7, 0x33, 0x81, 0xd7, 0xa6,
0x59, 0x31, 0x02, 0xa7, 0xba, 0x3e, 0x24, 0x31, 0x42, 0xc1, 0x65, 0xb4, 0x50, 0x57, 0xcc, 0xe7, 0x5e, 0x92, 0x98, 0xa2, 0xd0, 0x16, 0x59, 0xee, 0x6a, 0xe1, 0x83, 0x0d, 0xa2, 0x8f, 0xcd, 0x6d,
0x36, 0x67, 0x4d, 0xd8, 0xdc, 0xe6, 0xab, 0xcb, 0x49, 0x4c, 0x96, 0xd2, 0xd0, 0xba, 0x44, 0x23, 0xa9, 0xbd, 0x9a, 0x26, 0xec, 0x7a, 0x1e, 0xda, 0x94, 0x78, 0x04, 0xa2, 0x6f, 0xd9, 0x13, 0x9c,
0xce, 0x9a, 0x96, 0x3d, 0xc0, 0x59, 0xf1, 0x05, 0x74, 0x7f, 0xda, 0x44, 0xae, 0x2b, 0x1e, 0x4a, 0x95, 0x9c, 0x23, 0xf7, 0xe7, 0xbd, 0xc8, 0x5d, 0x0d, 0xa1, 0xa2, 0x5f, 0x12, 0x6a, 0xfe, 0x78,
0xfc, 0x39, 0xc2, 0xfa, 0xc7, 0x5e, 0x5d, 0xb1, 0x48, 0x1d, 0x30, 0xc5, 0x1a, 0x4c, 0x9a, 0x49, 0xda, 0xd5, 0x22, 0xd2, 0x7b, 0x42, 0x8b, 0x9e, 0x50, 0xd9, 0x4b, 0xbd, 0xd4, 0x66, 0x69, 0xc2,
0x3d, 0x5f, 0x25, 0x49, 0x4c, 0xee, 0xf6, 0x3c, 0x78, 0xb8, 0x47, 0xa5, 0x06, 0xd1, 0x66, 0x8a, 0xee, 0x8e, 0x3c, 0x20, 0x7c, 0xca, 0x95, 0x01, 0xf1, 0x7e, 0x8e, 0xb2, 0xec, 0x0a, 0x2a, 0xb5,
0xb2, 0xec, 0x1c, 0x2a, 0xb6, 0xd1, 0x4d, 0xdd, 0x5a, 0xaa, 0xab, 0x88, 0x4b, 0xd9, 0x57, 0xbc, 0xc9, 0x0d, 0x33, 0xda, 0xec, 0xea, 0x08, 0x94, 0x1a, 0x2b, 0x9e, 0x43, 0xc5, 0xcd, 0x34, 0x61,
0x00, 0x8a, 0x1b, 0x49, 0x4c, 0xd6, 0x06, 0x8a, 0x25, 0x2a, 0x01, 0x95, 0x91, 0xcc, 0x23, 0xe3, 0xeb, 0x13, 0xc5, 0x26, 0x57, 0x88, 0x2a, 0x48, 0x56, 0x91, 0xe9, 0x3e, 0xb9, 0x6e, 0x86, 0x5b,
0x43, 0xb4, 0xa4, 0x9b, 0xcb, 0x75, 0x25, 0xc2, 0xbe, 0xe2, 0x1c, 0x28, 0xae, 0x27, 0x31, 0x59, 0x5d, 0x2d, 0xc3, 0xb1, 0x62, 0x1d, 0x15, 0x37, 0xd2, 0x84, 0xad, 0x4d, 0x14, 0x5b, 0x66, 0xdb,
0x1d, 0x28, 0x96, 0xf5, 0xb2, 0x0f, 0x33, 0x7a, 0xe3, 0x44, 0xfc, 0x43, 0x74, 0x5d, 0x37, 0x56, 0x87, 0x05, 0xbd, 0x59, 0x22, 0xfd, 0x19, 0xb9, 0x6a, 0x06, 0x9f, 0x7d, 0x15, 0xfa, 0x52, 0xf4,
0xbe, 0x08, 0x7d, 0xc1, 0x9a, 0x87, 0xc2, 0x95, 0xb0, 0x18, 0xe6, 0xb3, 0x4b, 0x4a, 0x6b, 0x55, 0xf7, 0xa5, 0xab, 0x70, 0x33, 0x2c, 0x15, 0xb7, 0x94, 0xd1, 0x7a, 0xc6, 0x63, 0x44, 0x70, 0x5f,
0x68, 0x07, 0x10, 0xd4, 0x17, 0xae, 0xb4, 0xec, 0x51, 0x92, 0xf5, 0xaf, 0x25, 0x44, 0x72, 0x06, 0xba, 0xca, 0xb2, 0xa7, 0x49, 0xd6, 0xdf, 0x2f, 0x13, 0x56, 0xb1, 0xc0, 0x9f, 0xba, 0x10, 0xe8,
0xf8, 0xb9, 0xcb, 0x03, 0xb5, 0x2f, 0x02, 0x15, 0x09, 0xb8, 0x94, 0xf6, 0x7c, 0x5f, 0x1c, 0x8c, 0x5d, 0x19, 0xe8, 0x48, 0xe2, 0xa5, 0x74, 0xe4, 0xfb, 0x7c, 0x6f, 0xf6, 0x52, 0x3a, 0xca, 0xc9,
0x5f, 0x4a, 0x7b, 0x39, 0xa9, 0xd7, 0xb4, 0xec, 0x0c, 0x12, 0xff, 0x04, 0xdd, 0xec, 0x3d, 0x1d, 0xbd, 0xbe, 0x65, 0x17, 0x90, 0xf4, 0x97, 0xe4, 0xc6, 0xe8, 0xd7, 0x1e, 0x28, 0x27, 0xf2, 0xb0,
0x70, 0xe9, 0x44, 0x1e, 0xec, 0x3a, 0xe9, 0x05, 0x35, 0xf3, 0x5e, 0xfa, 0x02, 0xcd, 0x01, 0xca, 0xeb, 0xe4, 0x17, 0xd4, 0xc2, 0x73, 0x19, 0x0b, 0xf4, 0x27, 0x28, 0xcb, 0xae, 0xe2, 0xd2, 0x1f,
0xb2, 0xf3, 0xb8, 0xf8, 0x19, 0x5a, 0xec, 0x35, 0x1f, 0x31, 0x37, 0xbd, 0xac, 0xae, 0x24, 0x31, 0x90, 0x95, 0xd1, 0xf0, 0x81, 0x70, 0xf3, 0xcb, 0xea, 0xed, 0x34, 0x61, 0x37, 0xa6, 0xa4, 0xb4,
0xb9, 0x39, 0x22, 0xa5, 0x98, 0x6b, 0xd9, 0x59, 0xac, 0x5e, 0x32, 0x35, 0xce, 0xa3, 0x17, 0x35, 0x70, 0x2d, 0xbb, 0x88, 0x35, 0x5b, 0xa6, 0x03, 0x10, 0x3d, 0xef, 0x98, 0x95, 0xaa, 0x97, 0xaf,
0x3d, 0x52, 0x73, 0xc3, 0x57, 0xe4, 0x90, 0xf3, 0x88, 0x7a, 0xa1, 0xb4, 0xec, 0x1e, 0x06, 0xff, 0xc8, 0x21, 0x40, 0xc4, 0xbd, 0x50, 0x59, 0xf6, 0x08, 0x43, 0x7f, 0x4a, 0x2e, 0xe7, 0x7f, 0x76,
0x00, 0x5d, 0x4d, 0x7f, 0xd6, 0x55, 0xe4, 0x05, 0x6e, 0x7a, 0x43, 0x5c, 0x4d, 0x62, 0x72, 0x7b, 0x75, 0xe4, 0x05, 0x6e, 0x7e, 0x43, 0x5c, 0x4b, 0x13, 0x76, 0xab, 0x4c, 0x32, 0xcf, 0xdf, 0x0b,
0x98, 0xa4, 0xdf, 0xbf, 0x17, 0xb8, 0x96, 0x3d, 0x4c, 0xc0, 0x35, 0x84, 0x61, 0x18, 0x6b, 0x22, 0x5c, 0xcb, 0x2e, 0x13, 0x68, 0x87, 0x50, 0x5c, 0xc6, 0x8e, 0x8c, 0xf4, 0x81, 0xcc, 0x9b, 0x46,
0x52, 0x47, 0x22, 0xdd, 0x34, 0xd2, 0x6d, 0x20, 0x33, 0x87, 0x98, 0xc6, 0xd0, 0x50, 0x44, 0x8a, 0xde, 0x06, 0x0a, 0xef, 0x90, 0x30, 0x18, 0x1e, 0xca, 0x48, 0x73, 0x2d, 0x79, 0xde, 0x77, 0x2c,
0x2a, 0x41, 0xd3, 0x7d, 0xc7, 0xb2, 0x73, 0xb8, 0xb8, 0x8a, 0xae, 0x41, 0xeb, 0x27, 0x41, 0x33, 0xbb, 0x82, 0x4b, 0xdb, 0xe4, 0x0a, 0x8e, 0x7e, 0x16, 0xf4, 0x43, 0xe9, 0x05, 0x5a, 0x35, 0x2e,
0x14, 0x5e, 0xa0, 0x64, 0xf1, 0x32, 0xf4, 0x24, 0x13, 0xca, 0xa8, 0xf1, 0x1e, 0xc0, 0xb2, 0x47, 0xe2, 0x4c, 0x0a, 0xa1, 0x32, 0x35, 0x18, 0x01, 0x2c, 0x7b, 0x8a, 0x41, 0x7f, 0x4d, 0x56, 0x47,
0x18, 0xf8, 0x67, 0x68, 0xb9, 0x37, 0x2a, 0xc3, 0xc1, 0xcc, 0x9e, 0xb0, 0x99, 0xc4, 0x84, 0x8c, 0xab, 0x52, 0x0e, 0x96, 0xf5, 0x84, 0x07, 0x69, 0xc2, 0xd8, 0xd4, 0x5a, 0xce, 0x64, 0xab, 0x56,
0x8c, 0xe5, 0x58, 0xb6, 0x7c, 0x05, 0xfc, 0x12, 0x2d, 0xf5, 0x0a, 0x83, 0x84, 0x0b, 0x90, 0xf0, 0xa0, 0x2f, 0xc8, 0xf5, 0x51, 0x61, 0x92, 0x70, 0x19, 0x13, 0xde, 0x4b, 0x13, 0x76, 0x67, 0x4a,
0x5e, 0x12, 0x93, 0x3b, 0x23, 0xb2, 0x99, 0x90, 0xe3, 0x3c, 0xfc, 0x1a, 0xdd, 0x80, 0x8f, 0x27, 0xb6, 0x10, 0x72, 0x96, 0x47, 0x7f, 0x45, 0xae, 0xe2, 0xc7, 0x13, 0x7e, 0xb5, 0x71, 0xae, 0xbd,
0xf8, 0x6a, 0xa3, 0xf4, 0xb4, 0x44, 0xcb, 0x70, 0x41, 0x59, 0x2c, 0xad, 0x6d, 0x0f, 0x3e, 0xb0, 0x10, 0xef, 0x27, 0x2b, 0xcd, 0xbb, 0xdb, 0x93, 0xef, 0xab, 0xed, 0x29, 0x48, 0xfb, 0x66, 0x9a,
0xb6, 0x47, 0x31, 0xd9, 0x3d, 0x65, 0xd0, 0x6a, 0xd9, 0x8b, 0x1a, 0xf8, 0x89, 0x72, 0x9a, 0xaf, 0xb0, 0x6b, 0x99, 0xcf, 0x78, 0xd0, 0xb2, 0x57, 0x0c, 0xec, 0x33, 0xed, 0xf4, 0x0f, 0xbc, 0x90,
0x4a, 0xe5, 0x31, 0xed, 0x32, 0xdd, 0x83, 0xbb, 0xc9, 0x34, 0xed, 0x32, 0xdd, 0xcb, 0xd1, 0x2e, 0xbe, 0x22, 0xd7, 0x8a, 0xac, 0xd7, 0x2d, 0xde, 0xc4, 0x8b, 0xc9, 0x4a, 0x73, 0xfd, 0x34, 0x65,
0xd3, 0xbd, 0xac, 0x76, 0x79, 0x2f, 0x47, 0xbb, 0x04, 0x77, 0x92, 0xe9, 0xda, 0xa5, 0x5c, 0xed, 0x83, 0x29, 0x36, 0xab, 0xc9, 0x68, 0x41, 0xfb, 0x65, 0xab, 0x59, 0xa1, 0xdd, 0xc2, 0x0b, 0xc9,
0xd2, 0x90, 0x76, 0x09, 0xff, 0x14, 0x5d, 0xcf, 0xf2, 0x94, 0x17, 0xc2, 0x8d, 0x65, 0xb1, 0x74, 0x7c, 0xed, 0x56, 0xa5, 0x76, 0xab, 0xa4, 0xdd, 0xa2, 0x7f, 0xa9, 0x91, 0xf5, 0x8c, 0x38, 0xfe,
0x77, 0x92, 0xb4, 0xf2, 0xc2, 0xea, 0xad, 0x24, 0x26, 0x37, 0xb2, 0xca, 0xca, 0x0b, 0x33, 0xc2, 0x56, 0xe5, 0x3c, 0x6a, 0xf1, 0x8f, 0x79, 0x8b, 0xf7, 0x40, 0x8b, 0xc6, 0x9b, 0x1a, 0x3a, 0x6d,
0x47, 0x5e, 0x88, 0x4f, 0xd1, 0x8a, 0x61, 0xf5, 0x3f, 0x83, 0x29, 0x8d, 0xca, 0xb4, 0x42, 0x9f, 0xcd, 0x3a, 0x55, 0x13, 0xda, 0xf7, 0xd3, 0x84, 0xdd, 0xcb, 0x5c, 0xab, 0x11, 0x96, 0xbd, 0x6a,
0x15, 0xdf, 0x14, 0xc0, 0x61, 0x73, 0xdc, 0x61, 0x0c, 0x9b, 0xdd, 0x7b, 0xc6, 0x8a, 0x96, 0xbd, 0x04, 0x5e, 0x8d, 0x8a, 0x76, 0xeb, 0xe3, 0x56, 0x1b, 0xb4, 0xa0, 0x5f, 0x93, 0x9b, 0x99, 0x72,
0xa4, 0x69, 0xaf, 0x7b, 0xed, 0x76, 0xb9, 0xf2, 0x0c, 0xff, 0xb1, 0x80, 0xee, 0xe5, 0x89, 0x3d, 0xf6, 0x55, 0xcc, 0xf9, 0xeb, 0xa7, 0xfc, 0x09, 0x6f, 0x36, 0xfe, 0x71, 0x0e, 0x23, 0x6c, 0xce,
0xa1, 0x25, 0xca, 0xfc, 0xb0, 0xc5, 0x8a, 0x7f, 0x37, 0xf6, 0x8f, 0xce, 0xb3, 0xef, 0x33, 0xaa, 0x46, 0x28, 0x03, 0x8b, 0x47, 0x4f, 0xb9, 0x62, 0xd9, 0x57, 0x0c, 0x61, 0x17, 0x07, 0x5f, 0x3e,
0x56, 0x12, 0x93, 0xf5, 0xbc, 0x10, 0x7d, 0x88, 0x65, 0xdf, 0x1e, 0x89, 0xf2, 0xa4, 0xf4, 0x5c, 0x7d, 0xd2, 0xa4, 0xbf, 0x23, 0xd7, 0x73, 0x89, 0x6c, 0x69, 0x70, 0xae, 0xdf, 0xd4, 0xd1, 0xe8,
0x17, 0xf0, 0xef, 0x0b, 0x68, 0x2d, 0x5f, 0xbd, 0x4c, 0x1b, 0x5c, 0xb1, 0xe2, 0x3f, 0x4c, 0x9c, 0x5e, 0x85, 0xd1, 0x04, 0x55, 0x6c, 0x52, 0x85, 0x61, 0xcb, 0xbe, 0x8c, 0x16, 0x66, 0x04, 0x67,
0xad, 0xf3, 0xe3, 0x18, 0x42, 0xf5, 0x7e, 0x12, 0x93, 0x7b, 0xf9, 0x69, 0x0c, 0xc2, 0xb2, 0x97, 0x33, 0x76, 0x38, 0x29, 0x38, 0xfc, 0xff, 0x54, 0x87, 0x93, 0x6a, 0x87, 0x93, 0x19, 0x87, 0x57,
0x47, 0xc3, 0x94, 0xab, 0x5c, 0x31, 0xfc, 0x25, 0xba, 0x65, 0x94, 0xcd, 0x3f, 0x0f, 0x94, 0x9e, 0x63, 0x87, 0xbf, 0xd5, 0x16, 0xba, 0x8f, 0x35, 0xfe, 0x7b, 0x11, 0x4d, 0x77, 0x8a, 0xa6, 0x0b,
0xee, 0xd2, 0x8f, 0xe9, 0x93, 0xe2, 0x9f, 0x2f, 0x40, 0x84, 0x8d, 0xf1, 0x08, 0xc3, 0xc0, 0xec, 0xf0, 0x8a, 0x4d, 0xbf, 0x37, 0xaa, 0x71, 0x99, 0x15, 0xcd, 0xa7, 0xf2, 0x02, 0x57, 0xc1, 0x6f,
0xf1, 0x3e, 0x5c, 0xb1, 0xec, 0x6b, 0x9a, 0xb0, 0x0f, 0x8d, 0xaf, 0x76, 0x3f, 0x7e, 0x92, 0xeb, 0x6b, 0x0b, 0x9c, 0xb4, 0x8d, 0xff, 0x65, 0x01, 0x1f, 0x2f, 0x1a, 0x10, 0x59, 0xc5, 0xfe, 0x34,
0xf5, 0x94, 0xee, 0x16, 0xff, 0x32, 0x8b, 0xd7, 0x53, 0xba, 0x3b, 0xc1, 0xeb, 0x29, 0xdd, 0x1d, 0x89, 0x67, 0x4e, 0x27, 0x65, 0xd9, 0x67, 0x9b, 0xb6, 0x6f, 0xbe, 0xf9, 0xcf, 0xc6, 0x7b, 0x6f,
0xf1, 0x7a, 0xba, 0x3b, 0xc1, 0xab, 0x52, 0xfc, 0xeb, 0x6c, 0x5e, 0x95, 0x89, 0x5e, 0x95, 0x51, 0xde, 0x6e, 0xd4, 0xfe, 0xf5, 0x76, 0xa3, 0xf6, 0xef, 0xb7, 0x1b, 0xb5, 0x6f, 0xdf, 0x6d, 0xbc,
0xaf, 0x0a, 0xfe, 0x25, 0x5a, 0x4a, 0x25, 0xcc, 0xcc, 0x87, 0x77, 0xf8, 0xd5, 0x1c, 0x18, 0xdd, 0xd7, 0x7b, 0x1f, 0xff, 0xa1, 0xd2, 0xfa, 0x2e, 0x00, 0x00, 0xff, 0xff, 0x1d, 0xef, 0x79, 0xe4,
0xcb, 0x31, 0x1a, 0xa0, 0xb2, 0x07, 0x5c, 0xa6, 0xd9, 0xb2, 0xaf, 0x82, 0x85, 0x6e, 0x81, 0xb7, 0x4a, 0x12, 0x00, 0x00,
0xd4, 0x77, 0x38, 0xcb, 0x38, 0xfc, 0x7f, 0xa2, 0xc3, 0x59, 0xbe, 0xc3, 0xd9, 0x98, 0xc3, 0xeb,
0xbe, 0xc3, 0x9f, 0x0a, 0x33, 0xdd, 0xe5, 0x8b, 0xff, 0xbd, 0x0c, 0xa6, 0x3b, 0x59, 0xd3, 0x19,
0x78, 0xd9, 0x45, 0xdb, 0xe8, 0xd5, 0xa8, 0x30, 0x45, 0xcb, 0x9e, 0xe9, 0x33, 0xe2, 0xeb, 0xc2,
0x0c, 0xb7, 0xb4, 0xe2, 0xff, 0x4c, 0xc0, 0xc7, 0xb3, 0x06, 0x04, 0x56, 0xf6, 0x6c, 0x1b, 0xc4,
0xd3, 0x37, 0x1b, 0x69, 0xd9, 0xe7, 0x9b, 0x56, 0x6f, 0xbd, 0xf9, 0xcf, 0xfa, 0x7b, 0x6f, 0xde,
0xae, 0x17, 0xfe, 0xf9, 0x76, 0xbd, 0xf0, 0xef, 0xb7, 0xeb, 0x85, 0xaf, 0xdf, 0xad, 0xbf, 0xd7,
0x78, 0x1f, 0xfe, 0x8c, 0x2b, 0x7f, 0x13, 0x00, 0x00, 0xff, 0xff, 0x5e, 0xbd, 0x27, 0x38, 0x86,
0x14, 0x00, 0x00,
} }

View File

@ -73,18 +73,13 @@ message ConfigClientMachineAgentControl {
int64 DatabasePortToConnect = 8 [(gogoproto.moretags) = "yaml:\"database_port_to_connect\""]; int64 DatabasePortToConnect = 8 [(gogoproto.moretags) = "yaml:\"database_port_to_connect\""];
repeated string DatabaseEndpoints = 9 [(gogoproto.moretags) = "yaml:\"database_endpoints\""]; repeated string DatabaseEndpoints = 9 [(gogoproto.moretags) = "yaml:\"database_endpoints\""];
flag__etcd__v2_3 flag__etcd__v2_3 = 100 [(gogoproto.moretags) = "yaml:\"etcd__v2_3\""]; flag__etcd__tip flag__etcd__tip = 100 [(gogoproto.moretags) = "yaml:\"etcd__tip\""];
flag__etcd__v3_1 flag__etcd__v3_1 = 101 [(gogoproto.moretags) = "yaml:\"etcd__v3_1\""]; flag__etcd__v3_2 flag__etcd__v3_2 = 101 [(gogoproto.moretags) = "yaml:\"etcd__v3_2\""];
flag__etcd__v3_2 flag__etcd__v3_2 = 102 [(gogoproto.moretags) = "yaml:\"etcd__v3_2\""]; flag__etcd__v3_3 flag__etcd__v3_3 = 102 [(gogoproto.moretags) = "yaml:\"etcd__v3_3\""];
flag__etcd__tip flag__etcd__tip = 103 [(gogoproto.moretags) = "yaml:\"etcd__tip\""];
flag__zookeeper__r3_4_9 flag__zookeeper__r3_4_9 = 200 [(gogoproto.moretags) = "yaml:\"zookeeper__r3_4_9\""]; flag__zookeeper__r3_5_3_beta flag__zookeeper__r3_5_3_beta = 200 [(gogoproto.moretags) = "yaml:\"zookeeper__r3_5_3_beta\""];
flag__zookeeper__r3_5_2_alpha flag__zookeeper__r3_5_2_alpha = 201 [(gogoproto.moretags) = "yaml:\"zookeeper__r3_5_2_alpha\""];
flag__zookeeper__r3_5_3_beta flag__zookeeper__r3_5_3_beta = 202 [(gogoproto.moretags) = "yaml:\"zookeeper__r3_5_3_beta\""];
flag__consul__v0_7_5 flag__consul__v0_7_5 = 300 [(gogoproto.moretags) = "yaml:\"consul__v0_7_5\""]; flag__consul__v1_0_2 flag__consul__v1_0_2 = 300 [(gogoproto.moretags) = "yaml:\"consul__v1_0_2\""];
flag__consul__v0_8_0 flag__consul__v0_8_0 = 301 [(gogoproto.moretags) = "yaml:\"consul__v0_8_0\""];
flag__consul__v0_8_4 flag__consul__v0_8_4 = 302 [(gogoproto.moretags) = "yaml:\"consul__v0_8_4\""];
flag__cetcd__beta flag__cetcd__beta = 400 [(gogoproto.moretags) = "yaml:\"cetcd__beta\""]; flag__cetcd__beta flag__cetcd__beta = 400 [(gogoproto.moretags) = "yaml:\"cetcd__beta\""];
flag__zetcd__beta flag__zetcd__beta = 500 [(gogoproto.moretags) = "yaml:\"zetcd__beta\""]; flag__zetcd__beta flag__zetcd__beta = 500 [(gogoproto.moretags) = "yaml:\"zetcd__beta\""];

View File

@ -19,47 +19,37 @@ var _ = math.Inf
type DatabaseID int32 type DatabaseID int32
const ( const (
DatabaseID_etcd__v2_3 DatabaseID = 0 // https://github.com/coreos/etcd/releases
DatabaseID_etcd__v3_1 DatabaseID = 1 DatabaseID_etcd__tip DatabaseID = 0
DatabaseID_etcd__v3_2 DatabaseID = 2 DatabaseID_etcd__v3_2 DatabaseID = 1
DatabaseID_etcd__tip DatabaseID = 3 DatabaseID_etcd__v3_3 DatabaseID = 2
DatabaseID_zookeeper__r3_4_9 DatabaseID = 10 // https://zookeeper.apache.org/releases.html
DatabaseID_zookeeper__r3_5_2_alpha DatabaseID = 11 DatabaseID_zookeeper__r3_5_3_beta DatabaseID = 100
DatabaseID_zookeeper__r3_5_3_beta DatabaseID = 12 // https://github.com/hashicorp/consul/releases
DatabaseID_consul__v0_7_5 DatabaseID = 20 DatabaseID_consul__v1_0_2 DatabaseID = 200
DatabaseID_consul__v0_8_0 DatabaseID = 21 // https://github.com/coreos/zetcd/releases
DatabaseID_consul__v0_8_4 DatabaseID = 22 DatabaseID_zetcd__beta DatabaseID = 300
DatabaseID_zetcd__beta DatabaseID = 30 // https://github.com/coreos/cetcd/releases
DatabaseID_cetcd__beta DatabaseID = 40 DatabaseID_cetcd__beta DatabaseID = 400
) )
var DatabaseID_name = map[int32]string{ var DatabaseID_name = map[int32]string{
0: "etcd__v2_3", 0: "etcd__tip",
1: "etcd__v3_1", 1: "etcd__v3_2",
2: "etcd__v3_2", 2: "etcd__v3_3",
3: "etcd__tip", 100: "zookeeper__r3_5_3_beta",
10: "zookeeper__r3_4_9", 200: "consul__v1_0_2",
11: "zookeeper__r3_5_2_alpha", 300: "zetcd__beta",
12: "zookeeper__r3_5_3_beta", 400: "cetcd__beta",
20: "consul__v0_7_5",
21: "consul__v0_8_0",
22: "consul__v0_8_4",
30: "zetcd__beta",
40: "cetcd__beta",
} }
var DatabaseID_value = map[string]int32{ var DatabaseID_value = map[string]int32{
"etcd__v2_3": 0, "etcd__tip": 0,
"etcd__v3_1": 1, "etcd__v3_2": 1,
"etcd__v3_2": 2, "etcd__v3_3": 2,
"etcd__tip": 3, "zookeeper__r3_5_3_beta": 100,
"zookeeper__r3_4_9": 10, "consul__v1_0_2": 200,
"zookeeper__r3_5_2_alpha": 11, "zetcd__beta": 300,
"zookeeper__r3_5_3_beta": 12, "cetcd__beta": 400,
"consul__v0_7_5": 20,
"consul__v0_8_0": 21,
"consul__v0_8_4": 22,
"zetcd__beta": 30,
"cetcd__beta": 40,
} }
func (x DatabaseID) String() string { func (x DatabaseID) String() string {
@ -74,22 +64,20 @@ func init() {
func init() { proto.RegisterFile("dbtesterpb/database_id.proto", fileDescriptorDatabaseId) } func init() { proto.RegisterFile("dbtesterpb/database_id.proto", fileDescriptorDatabaseId) }
var fileDescriptorDatabaseId = []byte{ var fileDescriptorDatabaseId = []byte{
// 263 bytes of a gzipped FileDescriptorProto // 226 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0x41, 0x4e, 0xeb, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0x49, 0x2a, 0x49,
0x10, 0x86, 0xe3, 0xf7, 0x24, 0x24, 0xa6, 0x50, 0x06, 0xab, 0x2d, 0x52, 0x41, 0x5e, 0x23, 0x24, 0x2d, 0x2e, 0x49, 0x2d, 0x2a, 0x48, 0xd2, 0x4f, 0x49, 0x2c, 0x49, 0x4c, 0x4a, 0x2c, 0x4e, 0x8d,
0x9a, 0x12, 0xb7, 0x02, 0xb6, 0xa8, 0x1b, 0x4e, 0x31, 0xb2, 0x13, 0x93, 0x46, 0x14, 0x6c, 0x25, 0xcf, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0xc8, 0x4a, 0xe9, 0xa6, 0x67,
0x4e, 0x17, 0x3d, 0x09, 0x47, 0xea, 0x92, 0x23, 0x40, 0x38, 0x05, 0x3b, 0x84, 0x83, 0x44, 0x5b, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xa7, 0xe7, 0xeb, 0x83, 0x95,
0x76, 0xfe, 0xbe, 0xdf, 0xf3, 0x6b, 0x34, 0x70, 0x96, 0x69, 0x6f, 0x2a, 0x6f, 0x4a, 0xa7, 0xe3, 0x24, 0x95, 0xa6, 0x81, 0x79, 0x60, 0x0e, 0x98, 0x05, 0xd1, 0xaa, 0x35, 0x81, 0x91, 0x8b, 0xcb,
0x4c, 0x79, 0xa5, 0x55, 0x65, 0xa8, 0xc8, 0x46, 0xae, 0xb4, 0xde, 0x72, 0xf8, 0x4d, 0x87, 0x97, 0x05, 0x6a, 0xa0, 0xa7, 0x8b, 0x10, 0x2f, 0x17, 0x67, 0x6a, 0x49, 0x72, 0x4a, 0x7c, 0x7c, 0x49,
0x79, 0xe1, 0xe7, 0xb5, 0x1e, 0xa5, 0xf6, 0x29, 0xce, 0x6d, 0x6e, 0xe3, 0xf0, 0x45, 0xd7, 0x0f, 0x66, 0x81, 0x00, 0x83, 0x10, 0x1f, 0x17, 0x17, 0x84, 0x5b, 0x66, 0x1c, 0x6f, 0x24, 0xc0, 0x88,
0x81, 0x02, 0x84, 0x57, 0x3b, 0x7a, 0xf1, 0xc9, 0x00, 0x66, 0x3f, 0x85, 0xf7, 0x33, 0xde, 0x05, 0xc2, 0x37, 0x16, 0x60, 0x12, 0x92, 0xe2, 0x12, 0xab, 0xca, 0xcf, 0xcf, 0x4e, 0x4d, 0x2d, 0x48,
0x30, 0x3e, 0xcd, 0x88, 0x96, 0x09, 0x49, 0x8c, 0x36, 0x58, 0xd2, 0x15, 0xb2, 0x2d, 0x4e, 0xf0, 0x2d, 0x8a, 0x8f, 0x2f, 0x32, 0x8e, 0x37, 0x8d, 0x37, 0x8e, 0x4f, 0x4a, 0x2d, 0x49, 0x14, 0x48,
0x1f, 0x3f, 0x84, 0xfd, 0x96, 0x7d, 0xe1, 0xf0, 0x3f, 0xef, 0xc3, 0xf1, 0xca, 0xda, 0x47, 0x63, 0x11, 0x12, 0xe6, 0xe2, 0x4b, 0xce, 0xcf, 0x2b, 0x2e, 0xcd, 0x89, 0x8f, 0x2f, 0x33, 0x8c, 0x37,
0x9c, 0x29, 0x89, 0x4a, 0x49, 0x13, 0xba, 0x45, 0xe0, 0xa7, 0x70, 0xb2, 0xad, 0xa7, 0x94, 0x90, 0x88, 0x37, 0x12, 0x38, 0xc1, 0x28, 0x24, 0xc0, 0xc5, 0x5d, 0x05, 0x31, 0x01, 0xac, 0x6a, 0x0d,
0x5a, 0xb8, 0xb9, 0xc2, 0x0e, 0x1f, 0xc2, 0x60, 0x37, 0x94, 0xa4, 0x8d, 0x57, 0x78, 0xc0, 0x39, 0x13, 0x48, 0x24, 0x19, 0x49, 0x64, 0x02, 0xb3, 0x93, 0xc8, 0x89, 0x87, 0x72, 0x0c, 0x27, 0x1e,
0x74, 0x53, 0xfb, 0x5c, 0xd5, 0x0b, 0xa2, 0xe5, 0x98, 0xae, 0x69, 0x8a, 0xbd, 0x1d, 0x77, 0x43, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8c, 0xc7, 0x72, 0x0c, 0x49,
0x63, 0xec, 0xff, 0x71, 0x13, 0x1c, 0xf0, 0x23, 0xe8, 0xac, 0xda, 0xdd, 0x42, 0x99, 0xf8, 0x16, 0x6c, 0x60, 0xf7, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x30, 0x14, 0xdc, 0x70, 0x0a, 0x01,
0xe9, 0x86, 0x38, 0xbf, 0xeb, 0xad, 0xdf, 0x45, 0xb4, 0x6e, 0x04, 0x7b, 0x6d, 0x04, 0x7b, 0x6b, 0x00, 0x00,
0x04, 0x7b, 0xf9, 0x10, 0x91, 0xde, 0x0b, 0x87, 0x91, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x27,
0x43, 0x40, 0x47, 0x73, 0x01, 0x00, 0x00,
} }

View File

@ -12,19 +12,20 @@ option (gogoproto.goproto_getters_all) = false;
// of each database. Make sure to make accordingn changes in 'flag_*' whenever an ID // of each database. Make sure to make accordingn changes in 'flag_*' whenever an ID
// is added/removed. // is added/removed.
enum DatabaseID { enum DatabaseID {
etcd__v2_3 = 0; // https://github.com/coreos/etcd/releases
etcd__v3_1 = 1; etcd__tip = 0;
etcd__v3_2 = 2; etcd__v3_2 = 1;
etcd__tip = 3; etcd__v3_3 = 2;
zookeeper__r3_4_9 = 10; // https://zookeeper.apache.org/releases.html
zookeeper__r3_5_2_alpha = 11; zookeeper__r3_5_3_beta = 100;
zookeeper__r3_5_3_beta = 12;
consul__v0_7_5 = 20; // https://github.com/hashicorp/consul/releases
consul__v0_8_0 = 21; consul__v1_0_2 = 200;
consul__v0_8_4 = 22;
zetcd__beta = 30; // https://github.com/coreos/zetcd/releases
cetcd__beta = 40; zetcd__beta = 300;
// https://github.com/coreos/cetcd/releases
cetcd__beta = 400;
} }

View File

@ -46,24 +46,6 @@ func (m *Flag_Cetcd_Beta) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func encodeFixed64FlagCetcd(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32FlagCetcd(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintFlagCetcd(dAtA []byte, offset int, v uint64) int { func encodeVarintFlagCetcd(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)

View File

@ -16,38 +16,18 @@ var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
// See https://github.com/hashicorp/consul for more. // See https://github.com/hashicorp/consul for more.
type Flag_Consul_V0_7_5 struct { type Flag_Consul_V1_0_2 struct {
} }
func (m *Flag_Consul_V0_7_5) Reset() { *m = Flag_Consul_V0_7_5{} } func (m *Flag_Consul_V1_0_2) Reset() { *m = Flag_Consul_V1_0_2{} }
func (m *Flag_Consul_V0_7_5) String() string { return proto.CompactTextString(m) } func (m *Flag_Consul_V1_0_2) String() string { return proto.CompactTextString(m) }
func (*Flag_Consul_V0_7_5) ProtoMessage() {} func (*Flag_Consul_V1_0_2) ProtoMessage() {}
func (*Flag_Consul_V0_7_5) Descriptor() ([]byte, []int) { return fileDescriptorFlagConsul, []int{0} } func (*Flag_Consul_V1_0_2) Descriptor() ([]byte, []int) { return fileDescriptorFlagConsul, []int{0} }
// See https://github.com/hashicorp/consul for more.
type Flag_Consul_V0_8_0 struct {
}
func (m *Flag_Consul_V0_8_0) Reset() { *m = Flag_Consul_V0_8_0{} }
func (m *Flag_Consul_V0_8_0) String() string { return proto.CompactTextString(m) }
func (*Flag_Consul_V0_8_0) ProtoMessage() {}
func (*Flag_Consul_V0_8_0) Descriptor() ([]byte, []int) { return fileDescriptorFlagConsul, []int{1} }
// See https://github.com/hashicorp/consul for more.
type Flag_Consul_V0_8_4 struct {
}
func (m *Flag_Consul_V0_8_4) Reset() { *m = Flag_Consul_V0_8_4{} }
func (m *Flag_Consul_V0_8_4) String() string { return proto.CompactTextString(m) }
func (*Flag_Consul_V0_8_4) ProtoMessage() {}
func (*Flag_Consul_V0_8_4) Descriptor() ([]byte, []int) { return fileDescriptorFlagConsul, []int{2} }
func init() { func init() {
proto.RegisterType((*Flag_Consul_V0_7_5)(nil), "dbtesterpb.flag__consul__v0_7_5") proto.RegisterType((*Flag_Consul_V1_0_2)(nil), "dbtesterpb.flag__consul__v1_0_2")
proto.RegisterType((*Flag_Consul_V0_8_0)(nil), "dbtesterpb.flag__consul__v0_8_0")
proto.RegisterType((*Flag_Consul_V0_8_4)(nil), "dbtesterpb.flag__consul__v0_8_4")
} }
func (m *Flag_Consul_V0_7_5) Marshal() (dAtA []byte, err error) { func (m *Flag_Consul_V1_0_2) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA) n, err := m.MarshalTo(dAtA)
@ -57,7 +37,7 @@ func (m *Flag_Consul_V0_7_5) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil return dAtA[:n], nil
} }
func (m *Flag_Consul_V0_7_5) MarshalTo(dAtA []byte) (int, error) { func (m *Flag_Consul_V1_0_2) MarshalTo(dAtA []byte) (int, error) {
var i int var i int
_ = i _ = i
var l int var l int
@ -65,60 +45,6 @@ func (m *Flag_Consul_V0_7_5) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func (m *Flag_Consul_V0_8_0) 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 *Flag_Consul_V0_8_0) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
return i, nil
}
func (m *Flag_Consul_V0_8_4) 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 *Flag_Consul_V0_8_4) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
return i, nil
}
func encodeFixed64FlagConsul(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32FlagConsul(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintFlagConsul(dAtA []byte, offset int, v uint64) int { func encodeVarintFlagConsul(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)
@ -128,19 +54,7 @@ func encodeVarintFlagConsul(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v) dAtA[offset] = uint8(v)
return offset + 1 return offset + 1
} }
func (m *Flag_Consul_V0_7_5) Size() (n int) { func (m *Flag_Consul_V1_0_2) Size() (n int) {
var l int
_ = l
return n
}
func (m *Flag_Consul_V0_8_0) Size() (n int) {
var l int
_ = l
return n
}
func (m *Flag_Consul_V0_8_4) Size() (n int) {
var l int var l int
_ = l _ = l
return n return n
@ -159,7 +73,7 @@ func sovFlagConsul(x uint64) (n int) {
func sozFlagConsul(x uint64) (n int) { func sozFlagConsul(x uint64) (n int) {
return sovFlagConsul(uint64((x << 1) ^ uint64((int64(x) >> 63)))) return sovFlagConsul(uint64((x << 1) ^ uint64((int64(x) >> 63))))
} }
func (m *Flag_Consul_V0_7_5) Unmarshal(dAtA []byte) error { func (m *Flag_Consul_V1_0_2) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
@ -182,110 +96,10 @@ func (m *Flag_Consul_V0_7_5) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 { if wireType == 4 {
return fmt.Errorf("proto: flag__consul__v0_7_5: wiretype end group for non-group") return fmt.Errorf("proto: flag__consul__v1_0_2: wiretype end group for non-group")
} }
if fieldNum <= 0 { if fieldNum <= 0 {
return fmt.Errorf("proto: flag__consul__v0_7_5: illegal tag %d (wire type %d)", fieldNum, wire) return fmt.Errorf("proto: flag__consul__v1_0_2: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipFlagConsul(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthFlagConsul
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Flag_Consul_V0_8_0) 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 ErrIntOverflowFlagConsul
}
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: flag__consul__v0_8_0: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: flag__consul__v0_8_0: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipFlagConsul(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthFlagConsul
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Flag_Consul_V0_8_4) 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 ErrIntOverflowFlagConsul
}
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: flag__consul__v0_8_4: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: flag__consul__v0_8_4: illegal tag %d (wire type %d)", fieldNum, wire)
} }
switch fieldNum { switch fieldNum {
default: default:
@ -417,14 +231,14 @@ var (
func init() { proto.RegisterFile("dbtesterpb/flag_consul.proto", fileDescriptorFlagConsul) } func init() { proto.RegisterFile("dbtesterpb/flag_consul.proto", fileDescriptorFlagConsul) }
var fileDescriptorFlagConsul = []byte{ var fileDescriptorFlagConsul = []byte{
// 141 bytes of a gzipped FileDescriptorProto // 133 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0x49, 0x2a, 0x49, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0x49, 0x2a, 0x49,
0x2d, 0x2e, 0x49, 0x2d, 0x2a, 0x48, 0xd2, 0x4f, 0xcb, 0x49, 0x4c, 0x8f, 0x4f, 0xce, 0xcf, 0x2b, 0x2d, 0x2e, 0x49, 0x2d, 0x2a, 0x48, 0xd2, 0x4f, 0xcb, 0x49, 0x4c, 0x8f, 0x4f, 0xce, 0xcf, 0x2b,
0x2e, 0xcd, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0xc8, 0x4a, 0xe9, 0xa6, 0x67, 0x2e, 0xcd, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0xc8, 0x4a, 0xe9, 0xa6, 0x67,
0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xa7, 0xe7, 0xeb, 0x83, 0x95, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xa7, 0xe7, 0xeb, 0x83, 0x95,
0x24, 0x95, 0xa6, 0x81, 0x79, 0x60, 0x0e, 0x98, 0x05, 0xd1, 0xaa, 0x24, 0xc6, 0x25, 0x02, 0x36, 0x24, 0x95, 0xa6, 0x81, 0x79, 0x60, 0x0e, 0x98, 0x05, 0xd1, 0xaa, 0x24, 0xc6, 0x25, 0x02, 0x36,
0x0f, 0x6a, 0x60, 0x7c, 0x7c, 0x99, 0x41, 0xbc, 0x79, 0xbc, 0x29, 0x56, 0x71, 0x8b, 0x78, 0x03, 0x0f, 0x6a, 0x60, 0x7c, 0x7c, 0x99, 0x61, 0xbc, 0x41, 0xbc, 0x91, 0x93, 0xc8, 0x89, 0x87, 0x72,
0x1c, 0xe2, 0x26, 0x4e, 0x22, 0x27, 0x1e, 0xca, 0x31, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x0c, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8c, 0xc7,
0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x33, 0x1e, 0xcb, 0x31, 0x24, 0xb1, 0x81, 0x2d, 0x31, 0x06, 0x72, 0x0c, 0x49, 0x6c, 0x60, 0x4d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x25, 0xe5, 0xaa,
0x04, 0x00, 0x00, 0xff, 0xff, 0x31, 0xd1, 0x99, 0x57, 0xbf, 0x00, 0x00, 0x00, 0xa0, 0x8f, 0x00, 0x00, 0x00,
} }

View File

@ -9,13 +9,5 @@ option (gogoproto.unmarshaler_all) = true;
option (gogoproto.goproto_getters_all) = false; option (gogoproto.goproto_getters_all) = false;
// See https://github.com/hashicorp/consul for more. // See https://github.com/hashicorp/consul for more.
message flag__consul__v0_7_5 { message flag__consul__v1_0_2 {
}
// See https://github.com/hashicorp/consul for more.
message flag__consul__v0_8_0 {
}
// See https://github.com/hashicorp/consul for more.
message flag__consul__v0_8_4 {
} }

View File

@ -16,25 +16,15 @@ var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
// See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more. // See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more.
type Flag_Etcd_V2_3 struct { type Flag_Etcd_Tip struct {
SnapshotCount int64 `protobuf:"varint,1,opt,name=SnapshotCount,proto3" json:"SnapshotCount,omitempty" yaml:"snapshot_count"`
}
func (m *Flag_Etcd_V2_3) Reset() { *m = Flag_Etcd_V2_3{} }
func (m *Flag_Etcd_V2_3) String() string { return proto.CompactTextString(m) }
func (*Flag_Etcd_V2_3) ProtoMessage() {}
func (*Flag_Etcd_V2_3) Descriptor() ([]byte, []int) { return fileDescriptorFlagEtcd, []int{0} }
// See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more.
type Flag_Etcd_V3_1 struct {
SnapshotCount int64 `protobuf:"varint,1,opt,name=SnapshotCount,proto3" json:"SnapshotCount,omitempty" yaml:"snapshot_count"` SnapshotCount int64 `protobuf:"varint,1,opt,name=SnapshotCount,proto3" json:"SnapshotCount,omitempty" yaml:"snapshot_count"`
QuotaSizeBytes int64 `protobuf:"varint,2,opt,name=QuotaSizeBytes,proto3" json:"QuotaSizeBytes,omitempty" yaml:"quota_size_bytes"` QuotaSizeBytes int64 `protobuf:"varint,2,opt,name=QuotaSizeBytes,proto3" json:"QuotaSizeBytes,omitempty" yaml:"quota_size_bytes"`
} }
func (m *Flag_Etcd_V3_1) Reset() { *m = Flag_Etcd_V3_1{} } func (m *Flag_Etcd_Tip) Reset() { *m = Flag_Etcd_Tip{} }
func (m *Flag_Etcd_V3_1) String() string { return proto.CompactTextString(m) } func (m *Flag_Etcd_Tip) String() string { return proto.CompactTextString(m) }
func (*Flag_Etcd_V3_1) ProtoMessage() {} func (*Flag_Etcd_Tip) ProtoMessage() {}
func (*Flag_Etcd_V3_1) Descriptor() ([]byte, []int) { return fileDescriptorFlagEtcd, []int{1} } func (*Flag_Etcd_Tip) Descriptor() ([]byte, []int) { return fileDescriptorFlagEtcd, []int{0} }
// See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more. // See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more.
type Flag_Etcd_V3_2 struct { type Flag_Etcd_V3_2 struct {
@ -45,26 +35,25 @@ type Flag_Etcd_V3_2 struct {
func (m *Flag_Etcd_V3_2) Reset() { *m = Flag_Etcd_V3_2{} } func (m *Flag_Etcd_V3_2) Reset() { *m = Flag_Etcd_V3_2{} }
func (m *Flag_Etcd_V3_2) String() string { return proto.CompactTextString(m) } func (m *Flag_Etcd_V3_2) String() string { return proto.CompactTextString(m) }
func (*Flag_Etcd_V3_2) ProtoMessage() {} func (*Flag_Etcd_V3_2) ProtoMessage() {}
func (*Flag_Etcd_V3_2) Descriptor() ([]byte, []int) { return fileDescriptorFlagEtcd, []int{2} } func (*Flag_Etcd_V3_2) Descriptor() ([]byte, []int) { return fileDescriptorFlagEtcd, []int{1} }
// See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more. // See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more.
type Flag_Etcd_Tip struct { type Flag_Etcd_V3_3 struct {
SnapshotCount int64 `protobuf:"varint,1,opt,name=SnapshotCount,proto3" json:"SnapshotCount,omitempty" yaml:"snapshot_count"` SnapshotCount int64 `protobuf:"varint,1,opt,name=SnapshotCount,proto3" json:"SnapshotCount,omitempty" yaml:"snapshot_count"`
QuotaSizeBytes int64 `protobuf:"varint,2,opt,name=QuotaSizeBytes,proto3" json:"QuotaSizeBytes,omitempty" yaml:"quota_size_bytes"` QuotaSizeBytes int64 `protobuf:"varint,2,opt,name=QuotaSizeBytes,proto3" json:"QuotaSizeBytes,omitempty" yaml:"quota_size_bytes"`
} }
func (m *Flag_Etcd_Tip) Reset() { *m = Flag_Etcd_Tip{} } func (m *Flag_Etcd_V3_3) Reset() { *m = Flag_Etcd_V3_3{} }
func (m *Flag_Etcd_Tip) String() string { return proto.CompactTextString(m) } func (m *Flag_Etcd_V3_3) String() string { return proto.CompactTextString(m) }
func (*Flag_Etcd_Tip) ProtoMessage() {} func (*Flag_Etcd_V3_3) ProtoMessage() {}
func (*Flag_Etcd_Tip) Descriptor() ([]byte, []int) { return fileDescriptorFlagEtcd, []int{3} } func (*Flag_Etcd_V3_3) Descriptor() ([]byte, []int) { return fileDescriptorFlagEtcd, []int{2} }
func init() { func init() {
proto.RegisterType((*Flag_Etcd_V2_3)(nil), "dbtesterpb.flag__etcd__v2_3")
proto.RegisterType((*Flag_Etcd_V3_1)(nil), "dbtesterpb.flag__etcd__v3_1")
proto.RegisterType((*Flag_Etcd_V3_2)(nil), "dbtesterpb.flag__etcd__v3_2")
proto.RegisterType((*Flag_Etcd_Tip)(nil), "dbtesterpb.flag__etcd__tip") proto.RegisterType((*Flag_Etcd_Tip)(nil), "dbtesterpb.flag__etcd__tip")
proto.RegisterType((*Flag_Etcd_V3_2)(nil), "dbtesterpb.flag__etcd__v3_2")
proto.RegisterType((*Flag_Etcd_V3_3)(nil), "dbtesterpb.flag__etcd__v3_3")
} }
func (m *Flag_Etcd_V2_3) Marshal() (dAtA []byte, err error) { func (m *Flag_Etcd_Tip) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA) n, err := m.MarshalTo(dAtA)
@ -74,30 +63,7 @@ func (m *Flag_Etcd_V2_3) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil return dAtA[:n], nil
} }
func (m *Flag_Etcd_V2_3) MarshalTo(dAtA []byte) (int, error) { func (m *Flag_Etcd_Tip) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.SnapshotCount != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintFlagEtcd(dAtA, i, uint64(m.SnapshotCount))
}
return i, nil
}
func (m *Flag_Etcd_V3_1) 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 *Flag_Etcd_V3_1) MarshalTo(dAtA []byte) (int, error) {
var i int var i int
_ = i _ = i
var l int var l int
@ -143,7 +109,7 @@ func (m *Flag_Etcd_V3_2) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func (m *Flag_Etcd_Tip) Marshal() (dAtA []byte, err error) { func (m *Flag_Etcd_V3_3) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA) n, err := m.MarshalTo(dAtA)
@ -153,7 +119,7 @@ func (m *Flag_Etcd_Tip) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil return dAtA[:n], nil
} }
func (m *Flag_Etcd_Tip) MarshalTo(dAtA []byte) (int, error) { func (m *Flag_Etcd_V3_3) MarshalTo(dAtA []byte) (int, error) {
var i int var i int
_ = i _ = i
var l int var l int
@ -171,24 +137,6 @@ func (m *Flag_Etcd_Tip) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func encodeFixed64FlagEtcd(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32FlagEtcd(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintFlagEtcd(dAtA []byte, offset int, v uint64) int { func encodeVarintFlagEtcd(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)
@ -198,16 +146,7 @@ func encodeVarintFlagEtcd(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v) dAtA[offset] = uint8(v)
return offset + 1 return offset + 1
} }
func (m *Flag_Etcd_V2_3) Size() (n int) { func (m *Flag_Etcd_Tip) Size() (n int) {
var l int
_ = l
if m.SnapshotCount != 0 {
n += 1 + sovFlagEtcd(uint64(m.SnapshotCount))
}
return n
}
func (m *Flag_Etcd_V3_1) Size() (n int) {
var l int var l int
_ = l _ = l
if m.SnapshotCount != 0 { if m.SnapshotCount != 0 {
@ -231,7 +170,7 @@ func (m *Flag_Etcd_V3_2) Size() (n int) {
return n return n
} }
func (m *Flag_Etcd_Tip) Size() (n int) { func (m *Flag_Etcd_V3_3) Size() (n int) {
var l int var l int
_ = l _ = l
if m.SnapshotCount != 0 { if m.SnapshotCount != 0 {
@ -256,7 +195,7 @@ func sovFlagEtcd(x uint64) (n int) {
func sozFlagEtcd(x uint64) (n int) { func sozFlagEtcd(x uint64) (n int) {
return sovFlagEtcd(uint64((x << 1) ^ uint64((int64(x) >> 63)))) return sovFlagEtcd(uint64((x << 1) ^ uint64((int64(x) >> 63))))
} }
func (m *Flag_Etcd_V2_3) Unmarshal(dAtA []byte) error { func (m *Flag_Etcd_Tip) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
@ -279,79 +218,10 @@ func (m *Flag_Etcd_V2_3) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 { if wireType == 4 {
return fmt.Errorf("proto: flag__etcd__v2_3: wiretype end group for non-group") return fmt.Errorf("proto: flag__etcd__tip: wiretype end group for non-group")
} }
if fieldNum <= 0 { if fieldNum <= 0 {
return fmt.Errorf("proto: flag__etcd__v2_3: illegal tag %d (wire type %d)", fieldNum, wire) return fmt.Errorf("proto: flag__etcd__tip: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field SnapshotCount", wireType)
}
m.SnapshotCount = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagEtcd
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.SnapshotCount |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipFlagEtcd(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthFlagEtcd
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Flag_Etcd_V3_1) 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 ErrIntOverflowFlagEtcd
}
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: flag__etcd__v3_1: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: flag__etcd__v3_1: illegal tag %d (wire type %d)", fieldNum, wire)
} }
switch fieldNum { switch fieldNum {
case 1: case 1:
@ -501,7 +371,7 @@ func (m *Flag_Etcd_V3_2) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *Flag_Etcd_Tip) Unmarshal(dAtA []byte) error { func (m *Flag_Etcd_V3_3) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
@ -524,10 +394,10 @@ func (m *Flag_Etcd_Tip) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 { if wireType == 4 {
return fmt.Errorf("proto: flag__etcd__tip: wiretype end group for non-group") return fmt.Errorf("proto: flag__etcd__v3_3: wiretype end group for non-group")
} }
if fieldNum <= 0 { if fieldNum <= 0 {
return fmt.Errorf("proto: flag__etcd__tip: illegal tag %d (wire type %d)", fieldNum, wire) return fmt.Errorf("proto: flag__etcd__v3_3: illegal tag %d (wire type %d)", fieldNum, wire)
} }
switch fieldNum { switch fieldNum {
case 1: case 1:
@ -697,21 +567,20 @@ var (
func init() { proto.RegisterFile("dbtesterpb/flag_etcd.proto", fileDescriptorFlagEtcd) } func init() { proto.RegisterFile("dbtesterpb/flag_etcd.proto", fileDescriptorFlagEtcd) }
var fileDescriptorFlagEtcd = []byte{ var fileDescriptorFlagEtcd = []byte{
// 251 bytes of a gzipped FileDescriptorProto // 239 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4a, 0x49, 0x2a, 0x49, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4a, 0x49, 0x2a, 0x49,
0x2d, 0x2e, 0x49, 0x2d, 0x2a, 0x48, 0xd2, 0x4f, 0xcb, 0x49, 0x4c, 0x8f, 0x4f, 0x2d, 0x49, 0x4e, 0x2d, 0x2e, 0x49, 0x2d, 0x2a, 0x48, 0xd2, 0x4f, 0xcb, 0x49, 0x4c, 0x8f, 0x4f, 0x2d, 0x49, 0x4e,
0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0xc8, 0x49, 0xe9, 0xa6, 0x67, 0x96, 0x64, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0xc8, 0x49, 0xe9, 0xa6, 0x67, 0x96, 0x64,
0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xa7, 0xe7, 0xeb, 0x83, 0x95, 0x24, 0x95, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xa7, 0xe7, 0xeb, 0x83, 0x95, 0x24, 0x95,
0xa6, 0x81, 0x79, 0x60, 0x0e, 0x98, 0x05, 0xd1, 0xaa, 0x14, 0xcc, 0x25, 0x00, 0x36, 0x0d, 0x6c, 0xa6, 0x81, 0x79, 0x60, 0x0e, 0x98, 0x05, 0xd1, 0xaa, 0x34, 0x9d, 0x91, 0x8b, 0x1f, 0x6c, 0x1c,
0x5c, 0x7c, 0x7c, 0x99, 0x51, 0xbc, 0xb1, 0x90, 0x3d, 0x17, 0x6f, 0x70, 0x5e, 0x62, 0x41, 0x71, 0xd8, 0xbc, 0xf8, 0xf8, 0x92, 0xcc, 0x02, 0x21, 0x7b, 0x2e, 0xde, 0xe0, 0xbc, 0xc4, 0x82, 0xe2,
0x46, 0x7e, 0x89, 0x73, 0x7e, 0x69, 0x5e, 0x89, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb3, 0x93, 0xe4, 0x8c, 0xfc, 0x12, 0xe7, 0xfc, 0xd2, 0xbc, 0x12, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x66, 0x27, 0xc9,
0xa7, 0x7b, 0xf2, 0xa2, 0x95, 0x89, 0xb9, 0x39, 0x56, 0x4a, 0xc5, 0x50, 0xe9, 0xf8, 0x64, 0x90, 0x4f, 0xf7, 0xe4, 0x45, 0x2b, 0x13, 0x73, 0x73, 0xac, 0x94, 0x8a, 0xa1, 0xd2, 0xf1, 0xc9, 0x20,
0xbc, 0x52, 0x10, 0xaa, 0x7a, 0xa5, 0x19, 0x8c, 0x68, 0xa6, 0x1a, 0xc7, 0x1b, 0x52, 0x6c, 0xaa, 0x79, 0xa5, 0x20, 0x54, 0xf5, 0x42, 0xce, 0x5c, 0x7c, 0x81, 0xa5, 0xf9, 0x25, 0x89, 0xc1, 0x99,
0x90, 0x33, 0x17, 0x5f, 0x60, 0x69, 0x7e, 0x49, 0x62, 0x70, 0x66, 0x55, 0xaa, 0x53, 0x65, 0x49, 0x55, 0xa9, 0x4e, 0x95, 0x25, 0xa9, 0xc5, 0x12, 0x4c, 0x60, 0x13, 0xa4, 0x3f, 0xdd, 0x93, 0x17,
0x6a, 0xb1, 0x04, 0x13, 0xd8, 0x04, 0xe9, 0x4f, 0xf7, 0xe4, 0xc5, 0x21, 0x26, 0x14, 0x82, 0xe4, 0x87, 0x98, 0x50, 0x08, 0x92, 0x8f, 0x2f, 0xce, 0xac, 0x4a, 0x8d, 0x4f, 0x02, 0xa9, 0x50, 0x0a,
0xe3, 0x8b, 0x33, 0xab, 0x52, 0xe3, 0x93, 0x40, 0x2a, 0x94, 0x82, 0xd0, 0xb4, 0x60, 0x73, 0x9a, 0x42, 0xd3, 0xa2, 0x34, 0x83, 0x91, 0x4b, 0x00, 0xd9, 0x65, 0x65, 0xc6, 0xf1, 0x46, 0x83, 0xd7,
0xd1, 0x20, 0x71, 0xda, 0x74, 0x46, 0x2e, 0x7e, 0x64, 0xa7, 0x95, 0x64, 0x16, 0x0c, 0x0e, 0x97, 0x69, 0xc6, 0x83, 0xc3, 0x69, 0x4e, 0x22, 0x27, 0x1e, 0xca, 0x31, 0x9c, 0x78, 0x24, 0xc7, 0x78,
0x39, 0x89, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x33, 0x1e, 0xcb, 0x31, 0x24, 0xb1, 0x81, 0x23,
0x1e, 0xc9, 0x31, 0xce, 0x78, 0x2c, 0xc7, 0x90, 0xc4, 0x06, 0x4e, 0x41, 0xc6, 0x80, 0x00, 0x00, 0xdb, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x11, 0xc5, 0x8d, 0xd9, 0x45, 0x02, 0x00, 0x00,
0x00, 0xff, 0xff, 0x5c, 0xec, 0xd8, 0x68, 0x9a, 0x02, 0x00, 0x00,
} }

View File

@ -9,12 +9,7 @@ option (gogoproto.unmarshaler_all) = true;
option (gogoproto.goproto_getters_all) = false; option (gogoproto.goproto_getters_all) = false;
// See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more. // See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more.
message flag__etcd__v2_3 { message flag__etcd__tip {
int64 SnapshotCount = 1 [(gogoproto.moretags) = "yaml:\"snapshot_count\""];
}
// See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more.
message flag__etcd__v3_1 {
int64 SnapshotCount = 1 [(gogoproto.moretags) = "yaml:\"snapshot_count\""]; int64 SnapshotCount = 1 [(gogoproto.moretags) = "yaml:\"snapshot_count\""];
int64 QuotaSizeBytes = 2 [(gogoproto.moretags) = "yaml:\"quota_size_bytes\""]; int64 QuotaSizeBytes = 2 [(gogoproto.moretags) = "yaml:\"quota_size_bytes\""];
} }
@ -26,7 +21,7 @@ message flag__etcd__v3_2 {
} }
// See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more. // See https://github.com/coreos/etcd/blob/master/etcdmain/help.go for more.
message flag__etcd__tip { message flag__etcd__v3_3 {
int64 SnapshotCount = 1 [(gogoproto.moretags) = "yaml:\"snapshot_count\""]; int64 SnapshotCount = 1 [(gogoproto.moretags) = "yaml:\"snapshot_count\""];
int64 QuotaSizeBytes = 2 [(gogoproto.moretags) = "yaml:\"quota_size_bytes\""]; int64 QuotaSizeBytes = 2 [(gogoproto.moretags) = "yaml:\"quota_size_bytes\""];
} }

View File

@ -46,24 +46,6 @@ func (m *Flag_Zetcd_Beta) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func encodeFixed64FlagZetcd(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32FlagZetcd(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintFlagZetcd(dAtA []byte, offset int, v uint64) int { func encodeVarintFlagZetcd(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)

View File

@ -15,74 +15,6 @@ var _ = proto.Marshal
var _ = fmt.Errorf var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
type Flag_Zookeeper_R3_4_9 struct {
// JavaDJuteMaxBuffer is for '-Djute.maxbuffer' flag.
// It is the maximum size, in bytes, of a request or response.
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#Unsafe+Options for more.
JavaDJuteMaxBuffer uint64 `protobuf:"varint,1,opt,name=JavaDJuteMaxBuffer,proto3" json:"JavaDJuteMaxBuffer,omitempty" yaml:"java_d_jute_max_buffer"`
// JavaXms is for '-Xms' flag (minimum Java heap size).
// See https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html for more.
JavaXms string `protobuf:"bytes,2,opt,name=JavaXms,proto3" json:"JavaXms,omitempty" yaml:"java_xms"`
// JavaXmx is for '-Xmx' flag (maximum Java heap size).
// See https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html for more.
JavaXmx string `protobuf:"bytes,3,opt,name=JavaXmx,proto3" json:"JavaXmx,omitempty" yaml:"java_xmx"`
// MyID contains a single integer in human readable ASCII text that represents the server id.
// Each ZooKeeper server has a unique id. This id is used in two places: the myid file and the
// configuration file. The myid file identifies the server that corresponds to the given data directory.
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#sc_dataFileManagement for more.
MyID uint32 `protobuf:"varint,100,opt,name=MyID,proto3" json:"MyID,omitempty"`
// ClientPort is by default '2181'.
// No need to set manually. Inherited from 'database_port_to_connect'.
ClientPort int64 `protobuf:"varint,101,opt,name=ClientPort,proto3" json:"ClientPort,omitempty"`
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html for more.
TickTime int64 `protobuf:"varint,102,opt,name=TickTime,proto3" json:"TickTime,omitempty" yaml:"tick_time"`
InitLimit int64 `protobuf:"varint,103,opt,name=InitLimit,proto3" json:"InitLimit,omitempty" yaml:"init_limit"`
SyncLimit int64 `protobuf:"varint,104,opt,name=SyncLimit,proto3" json:"SyncLimit,omitempty" yaml:"sync_limit"`
SnapCount int64 `protobuf:"varint,105,opt,name=SnapCount,proto3" json:"SnapCount,omitempty" yaml:"snap_count"`
MaxClientConnections int64 `protobuf:"varint,106,opt,name=MaxClientConnections,proto3" json:"MaxClientConnections,omitempty" yaml:"max_client_connections"`
}
func (m *Flag_Zookeeper_R3_4_9) Reset() { *m = Flag_Zookeeper_R3_4_9{} }
func (m *Flag_Zookeeper_R3_4_9) String() string { return proto.CompactTextString(m) }
func (*Flag_Zookeeper_R3_4_9) ProtoMessage() {}
func (*Flag_Zookeeper_R3_4_9) Descriptor() ([]byte, []int) {
return fileDescriptorFlagZookeeper, []int{0}
}
type Flag_Zookeeper_R3_5_2Alpha struct {
// JavaDJuteMaxBuffer is for '-Djute.maxbuffer' flag.
// It is the maximum size, in bytes, of a request or response.
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#Unsafe+Options for more.
JavaDJuteMaxBuffer uint64 `protobuf:"varint,1,opt,name=JavaDJuteMaxBuffer,proto3" json:"JavaDJuteMaxBuffer,omitempty" yaml:"java_d_jute_max_buffer"`
// JavaXms is for '-Xms' flag (minimum Java heap size).
// See https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html for more.
JavaXms string `protobuf:"bytes,2,opt,name=JavaXms,proto3" json:"JavaXms,omitempty" yaml:"java_xms"`
// JavaXmx is for '-Xmx' flag (maximum Java heap size).
// See https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html for more.
JavaXmx string `protobuf:"bytes,3,opt,name=JavaXmx,proto3" json:"JavaXmx,omitempty" yaml:"java_xmx"`
// MyID contains a single integer in human readable ASCII text that represents the server id.
// Each ZooKeeper server has a unique id. This id is used in two places: the myid file and the
// configuration file. The myid file identifies the server that corresponds to the given data directory.
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#sc_dataFileManagement for more.
MyID uint32 `protobuf:"varint,100,opt,name=MyID,proto3" json:"MyID,omitempty"`
// ClientPort is by default '2181'.
// No need to set manually. Inherited from 'database_port_to_connect'.
ClientPort int64 `protobuf:"varint,101,opt,name=ClientPort,proto3" json:"ClientPort,omitempty"`
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html for more.
TickTime int64 `protobuf:"varint,102,opt,name=TickTime,proto3" json:"TickTime,omitempty" yaml:"tick_time"`
InitLimit int64 `protobuf:"varint,103,opt,name=InitLimit,proto3" json:"InitLimit,omitempty" yaml:"init_limit"`
SyncLimit int64 `protobuf:"varint,104,opt,name=SyncLimit,proto3" json:"SyncLimit,omitempty" yaml:"sync_limit"`
SnapCount int64 `protobuf:"varint,105,opt,name=SnapCount,proto3" json:"SnapCount,omitempty" yaml:"snap_count"`
MaxClientConnections int64 `protobuf:"varint,106,opt,name=MaxClientConnections,proto3" json:"MaxClientConnections,omitempty" yaml:"max_client_connections"`
}
func (m *Flag_Zookeeper_R3_5_2Alpha) Reset() { *m = Flag_Zookeeper_R3_5_2Alpha{} }
func (m *Flag_Zookeeper_R3_5_2Alpha) String() string { return proto.CompactTextString(m) }
func (*Flag_Zookeeper_R3_5_2Alpha) ProtoMessage() {}
func (*Flag_Zookeeper_R3_5_2Alpha) Descriptor() ([]byte, []int) {
return fileDescriptorFlagZookeeper, []int{1}
}
type Flag_Zookeeper_R3_5_3Beta struct { type Flag_Zookeeper_R3_5_3Beta struct {
// JavaDJuteMaxBuffer is for '-Djute.maxbuffer' flag. // JavaDJuteMaxBuffer is for '-Djute.maxbuffer' flag.
// It is the maximum size, in bytes, of a request or response. // It is the maximum size, in bytes, of a request or response.
@ -114,182 +46,12 @@ func (m *Flag_Zookeeper_R3_5_3Beta) Reset() { *m = Flag_Zookeeper_R3_5_3
func (m *Flag_Zookeeper_R3_5_3Beta) String() string { return proto.CompactTextString(m) } func (m *Flag_Zookeeper_R3_5_3Beta) String() string { return proto.CompactTextString(m) }
func (*Flag_Zookeeper_R3_5_3Beta) ProtoMessage() {} func (*Flag_Zookeeper_R3_5_3Beta) ProtoMessage() {}
func (*Flag_Zookeeper_R3_5_3Beta) Descriptor() ([]byte, []int) { func (*Flag_Zookeeper_R3_5_3Beta) Descriptor() ([]byte, []int) {
return fileDescriptorFlagZookeeper, []int{2} return fileDescriptorFlagZookeeper, []int{0}
} }
func init() { func init() {
proto.RegisterType((*Flag_Zookeeper_R3_4_9)(nil), "dbtesterpb.flag__zookeeper__r3_4_9")
proto.RegisterType((*Flag_Zookeeper_R3_5_2Alpha)(nil), "dbtesterpb.flag__zookeeper__r3_5_2_alpha")
proto.RegisterType((*Flag_Zookeeper_R3_5_3Beta)(nil), "dbtesterpb.flag__zookeeper__r3_5_3_beta") proto.RegisterType((*Flag_Zookeeper_R3_5_3Beta)(nil), "dbtesterpb.flag__zookeeper__r3_5_3_beta")
} }
func (m *Flag_Zookeeper_R3_4_9) 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 *Flag_Zookeeper_R3_4_9) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.JavaDJuteMaxBuffer != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.JavaDJuteMaxBuffer))
}
if len(m.JavaXms) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(len(m.JavaXms)))
i += copy(dAtA[i:], m.JavaXms)
}
if len(m.JavaXmx) > 0 {
dAtA[i] = 0x1a
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(len(m.JavaXmx)))
i += copy(dAtA[i:], m.JavaXmx)
}
if m.MyID != 0 {
dAtA[i] = 0xa0
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.MyID))
}
if m.ClientPort != 0 {
dAtA[i] = 0xa8
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.ClientPort))
}
if m.TickTime != 0 {
dAtA[i] = 0xb0
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.TickTime))
}
if m.InitLimit != 0 {
dAtA[i] = 0xb8
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.InitLimit))
}
if m.SyncLimit != 0 {
dAtA[i] = 0xc0
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.SyncLimit))
}
if m.SnapCount != 0 {
dAtA[i] = 0xc8
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.SnapCount))
}
if m.MaxClientConnections != 0 {
dAtA[i] = 0xd0
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.MaxClientConnections))
}
return i, nil
}
func (m *Flag_Zookeeper_R3_5_2Alpha) 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 *Flag_Zookeeper_R3_5_2Alpha) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.JavaDJuteMaxBuffer != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.JavaDJuteMaxBuffer))
}
if len(m.JavaXms) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(len(m.JavaXms)))
i += copy(dAtA[i:], m.JavaXms)
}
if len(m.JavaXmx) > 0 {
dAtA[i] = 0x1a
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(len(m.JavaXmx)))
i += copy(dAtA[i:], m.JavaXmx)
}
if m.MyID != 0 {
dAtA[i] = 0xa0
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.MyID))
}
if m.ClientPort != 0 {
dAtA[i] = 0xa8
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.ClientPort))
}
if m.TickTime != 0 {
dAtA[i] = 0xb0
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.TickTime))
}
if m.InitLimit != 0 {
dAtA[i] = 0xb8
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.InitLimit))
}
if m.SyncLimit != 0 {
dAtA[i] = 0xc0
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.SyncLimit))
}
if m.SnapCount != 0 {
dAtA[i] = 0xc8
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.SnapCount))
}
if m.MaxClientConnections != 0 {
dAtA[i] = 0xd0
i++
dAtA[i] = 0x6
i++
i = encodeVarintFlagZookeeper(dAtA, i, uint64(m.MaxClientConnections))
}
return i, nil
}
func (m *Flag_Zookeeper_R3_5_3Beta) Marshal() (dAtA []byte, err error) { func (m *Flag_Zookeeper_R3_5_3Beta) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
@ -374,24 +136,6 @@ func (m *Flag_Zookeeper_R3_5_3Beta) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func encodeFixed64FlagZookeeper(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32FlagZookeeper(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintFlagZookeeper(dAtA []byte, offset int, v uint64) int { func encodeVarintFlagZookeeper(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)
@ -401,82 +145,6 @@ func encodeVarintFlagZookeeper(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v) dAtA[offset] = uint8(v)
return offset + 1 return offset + 1
} }
func (m *Flag_Zookeeper_R3_4_9) Size() (n int) {
var l int
_ = l
if m.JavaDJuteMaxBuffer != 0 {
n += 1 + sovFlagZookeeper(uint64(m.JavaDJuteMaxBuffer))
}
l = len(m.JavaXms)
if l > 0 {
n += 1 + l + sovFlagZookeeper(uint64(l))
}
l = len(m.JavaXmx)
if l > 0 {
n += 1 + l + sovFlagZookeeper(uint64(l))
}
if m.MyID != 0 {
n += 2 + sovFlagZookeeper(uint64(m.MyID))
}
if m.ClientPort != 0 {
n += 2 + sovFlagZookeeper(uint64(m.ClientPort))
}
if m.TickTime != 0 {
n += 2 + sovFlagZookeeper(uint64(m.TickTime))
}
if m.InitLimit != 0 {
n += 2 + sovFlagZookeeper(uint64(m.InitLimit))
}
if m.SyncLimit != 0 {
n += 2 + sovFlagZookeeper(uint64(m.SyncLimit))
}
if m.SnapCount != 0 {
n += 2 + sovFlagZookeeper(uint64(m.SnapCount))
}
if m.MaxClientConnections != 0 {
n += 2 + sovFlagZookeeper(uint64(m.MaxClientConnections))
}
return n
}
func (m *Flag_Zookeeper_R3_5_2Alpha) Size() (n int) {
var l int
_ = l
if m.JavaDJuteMaxBuffer != 0 {
n += 1 + sovFlagZookeeper(uint64(m.JavaDJuteMaxBuffer))
}
l = len(m.JavaXms)
if l > 0 {
n += 1 + l + sovFlagZookeeper(uint64(l))
}
l = len(m.JavaXmx)
if l > 0 {
n += 1 + l + sovFlagZookeeper(uint64(l))
}
if m.MyID != 0 {
n += 2 + sovFlagZookeeper(uint64(m.MyID))
}
if m.ClientPort != 0 {
n += 2 + sovFlagZookeeper(uint64(m.ClientPort))
}
if m.TickTime != 0 {
n += 2 + sovFlagZookeeper(uint64(m.TickTime))
}
if m.InitLimit != 0 {
n += 2 + sovFlagZookeeper(uint64(m.InitLimit))
}
if m.SyncLimit != 0 {
n += 2 + sovFlagZookeeper(uint64(m.SyncLimit))
}
if m.SnapCount != 0 {
n += 2 + sovFlagZookeeper(uint64(m.SnapCount))
}
if m.MaxClientConnections != 0 {
n += 2 + sovFlagZookeeper(uint64(m.MaxClientConnections))
}
return n
}
func (m *Flag_Zookeeper_R3_5_3Beta) Size() (n int) { func (m *Flag_Zookeeper_R3_5_3Beta) Size() (n int) {
var l int var l int
_ = l _ = l
@ -528,526 +196,6 @@ func sovFlagZookeeper(x uint64) (n int) {
func sozFlagZookeeper(x uint64) (n int) { func sozFlagZookeeper(x uint64) (n int) {
return sovFlagZookeeper(uint64((x << 1) ^ uint64((int64(x) >> 63)))) return sovFlagZookeeper(uint64((x << 1) ^ uint64((int64(x) >> 63))))
} }
func (m *Flag_Zookeeper_R3_4_9) 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 ErrIntOverflowFlagZookeeper
}
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: flag__zookeeper__r3_4_9: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: flag__zookeeper__r3_4_9: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field JavaDJuteMaxBuffer", wireType)
}
m.JavaDJuteMaxBuffer = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.JavaDJuteMaxBuffer |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field JavaXms", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
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 ErrInvalidLengthFlagZookeeper
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.JavaXms = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field JavaXmx", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
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 ErrInvalidLengthFlagZookeeper
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.JavaXmx = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 100:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field MyID", wireType)
}
m.MyID = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.MyID |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 101:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ClientPort", wireType)
}
m.ClientPort = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ClientPort |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 102:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field TickTime", wireType)
}
m.TickTime = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.TickTime |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 103:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field InitLimit", wireType)
}
m.InitLimit = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.InitLimit |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 104:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field SyncLimit", wireType)
}
m.SyncLimit = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.SyncLimit |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 105:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field SnapCount", wireType)
}
m.SnapCount = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.SnapCount |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 106:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field MaxClientConnections", wireType)
}
m.MaxClientConnections = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.MaxClientConnections |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipFlagZookeeper(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthFlagZookeeper
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Flag_Zookeeper_R3_5_2Alpha) 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 ErrIntOverflowFlagZookeeper
}
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: flag__zookeeper__r3_5_2_alpha: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: flag__zookeeper__r3_5_2_alpha: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field JavaDJuteMaxBuffer", wireType)
}
m.JavaDJuteMaxBuffer = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.JavaDJuteMaxBuffer |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field JavaXms", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
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 ErrInvalidLengthFlagZookeeper
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.JavaXms = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field JavaXmx", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
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 ErrInvalidLengthFlagZookeeper
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.JavaXmx = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 100:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field MyID", wireType)
}
m.MyID = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.MyID |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 101:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ClientPort", wireType)
}
m.ClientPort = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ClientPort |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 102:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field TickTime", wireType)
}
m.TickTime = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.TickTime |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 103:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field InitLimit", wireType)
}
m.InitLimit = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.InitLimit |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 104:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field SyncLimit", wireType)
}
m.SyncLimit = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.SyncLimit |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 105:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field SnapCount", wireType)
}
m.SnapCount = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.SnapCount |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 106:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field MaxClientConnections", wireType)
}
m.MaxClientConnections = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFlagZookeeper
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.MaxClientConnections |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipFlagZookeeper(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthFlagZookeeper
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Flag_Zookeeper_R3_5_3Beta) Unmarshal(dAtA []byte) error { func (m *Flag_Zookeeper_R3_5_3Beta) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
@ -1416,34 +564,32 @@ var (
func init() { proto.RegisterFile("dbtesterpb/flag_zookeeper.proto", fileDescriptorFlagZookeeper) } func init() { proto.RegisterFile("dbtesterpb/flag_zookeeper.proto", fileDescriptorFlagZookeeper) }
var fileDescriptorFlagZookeeper = []byte{ var fileDescriptorFlagZookeeper = []byte{
// 459 bytes of a gzipped FileDescriptorProto // 419 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x95, 0x41, 0x8e, 0xd3, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x4f, 0x8e, 0xd3, 0x30,
0x14, 0x86, 0x27, 0x4c, 0x04, 0x8c, 0x25, 0x04, 0x98, 0x22, 0x2c, 0xc4, 0x24, 0x25, 0xab, 0x6e, 0x14, 0x87, 0xc7, 0x4c, 0x05, 0x8c, 0x25, 0x04, 0x98, 0x22, 0x59, 0x08, 0x92, 0x92, 0x55, 0x37,
0x66, 0x8a, 0x28, 0x2c, 0x60, 0x99, 0xce, 0x66, 0x46, 0x54, 0x82, 0x30, 0x48, 0xec, 0x2c, 0xc7, 0x33, 0x45, 0xaa, 0xd8, 0xb0, 0x4c, 0x67, 0x33, 0x23, 0x2a, 0x41, 0x18, 0x24, 0x76, 0x96, 0xe3,
0x75, 0x52, 0xb7, 0x89, 0x1d, 0x25, 0x2f, 0xa3, 0x94, 0x93, 0x70, 0x02, 0x36, 0x70, 0x90, 0x59, 0x3a, 0x19, 0xb7, 0xb5, 0x1d, 0x25, 0x2f, 0xa3, 0x94, 0x93, 0x70, 0x07, 0x2e, 0x32, 0x4b, 0x4e,
0x72, 0x82, 0x0a, 0xca, 0x0d, 0x7a, 0x02, 0x14, 0x47, 0x6d, 0x2a, 0xe8, 0xdc, 0xa0, 0x3b, 0xfb, 0x50, 0x41, 0xb9, 0x41, 0x4e, 0x80, 0xe2, 0x68, 0x92, 0x0a, 0xca, 0xee, 0xfd, 0xf9, 0xbe, 0x5f,
0xbd, 0xef, 0x7b, 0x51, 0xf4, 0x7e, 0xc9, 0xc8, 0x1d, 0x87, 0x20, 0x0a, 0x10, 0x79, 0x16, 0xf6, 0x14, 0x3d, 0x63, 0x7f, 0x11, 0x83, 0x2c, 0x40, 0xe6, 0x59, 0x3c, 0x49, 0xd6, 0x3c, 0x65, 0x5f,
0xa3, 0x84, 0xc5, 0xf4, 0x8b, 0xd6, 0x33, 0x21, 0x32, 0x91, 0x9f, 0x66, 0xb9, 0x06, 0x8d, 0x51, 0xad, 0x5d, 0x49, 0x99, 0xc9, 0xfc, 0x2c, 0xcb, 0x2d, 0x58, 0x82, 0x7b, 0xe0, 0xc5, 0x69, 0xaa,
0x0b, 0x3c, 0x3d, 0x89, 0x25, 0x4c, 0xca, 0xf0, 0x94, 0xeb, 0xb4, 0x1f, 0xeb, 0x58, 0xf7, 0x0d, 0xe0, 0xba, 0x8c, 0xcf, 0x84, 0xd5, 0x93, 0xd4, 0xa6, 0x76, 0xe2, 0x90, 0xb8, 0x4c, 0x5c, 0xe7,
0x12, 0x96, 0x91, 0xb9, 0x99, 0x8b, 0x39, 0x35, 0xaa, 0xf7, 0xcd, 0x46, 0x4f, 0xcc, 0xcc, 0x76, 0x1a, 0x57, 0xb5, 0x6a, 0xf0, 0x7d, 0x80, 0x5f, 0xba, 0xcc, 0x3e, 0x94, 0xb1, 0x7c, 0xca, 0xde,
0x28, 0xa5, 0xf9, 0x80, 0xbe, 0xa2, 0x6f, 0xf0, 0x07, 0x84, 0x2f, 0xd8, 0x15, 0x3b, 0xbb, 0x28, 0xb2, 0x29, 0x8b, 0x25, 0x70, 0xf2, 0x11, 0x93, 0x4b, 0x7e, 0xc3, 0xcf, 0x2f, 0x4b, 0x90, 0x73,
0x41, 0x8c, 0x58, 0xe5, 0x97, 0x51, 0x24, 0x72, 0x62, 0x75, 0xad, 0x9e, 0xed, 0x3f, 0x5f, 0x2d, 0x5e, 0x85, 0x65, 0x92, 0xc8, 0x9c, 0xa2, 0x11, 0x1a, 0x0f, 0xc2, 0xd7, 0xf5, 0xd6, 0x7f, 0xb5,
0xdc, 0xe3, 0x39, 0x4b, 0x93, 0xb7, 0xde, 0x94, 0x5d, 0x31, 0x3a, 0xa6, 0xd3, 0x12, 0x04, 0x4d, 0xe1, 0x7a, 0xfd, 0x2e, 0x58, 0xf2, 0x1b, 0xce, 0x16, 0x6c, 0x59, 0x82, 0x64, 0x9a, 0x57, 0x2c,
0x59, 0x45, 0x43, 0xc3, 0x79, 0xc1, 0x0e, 0x19, 0x9f, 0xa0, 0x3b, 0x75, 0xf5, 0x73, 0x5a, 0x90, 0x76, 0x5c, 0x10, 0x1d, 0x90, 0xc9, 0x29, 0x7e, 0xd0, 0x4c, 0xbf, 0xe8, 0x82, 0xde, 0x1b, 0xa1,
0x5b, 0x5d, 0xab, 0x77, 0xe4, 0x3f, 0x5a, 0x2d, 0xdc, 0xfb, 0x5b, 0x73, 0xaa, 0xb4, 0xf0, 0x82, 0xf1, 0x49, 0xf8, 0xac, 0xde, 0xfa, 0x8f, 0xf7, 0x72, 0x2a, 0x5d, 0x04, 0xd1, 0x1d, 0xd3, 0xe3,
0x35, 0xd3, 0xe2, 0x15, 0x39, 0xbc, 0x01, 0xaf, 0x36, 0x78, 0x85, 0x31, 0xb2, 0x47, 0xf3, 0xf3, 0x15, 0x3d, 0xfe, 0x0f, 0x5e, 0x75, 0x78, 0x45, 0x08, 0x1e, 0xcc, 0x37, 0x17, 0xe7, 0x74, 0x31,
0x33, 0x32, 0xee, 0x5a, 0xbd, 0x7b, 0x81, 0x39, 0x63, 0x07, 0xa1, 0x61, 0x22, 0x85, 0x82, 0xf7, 0x42, 0xe3, 0x47, 0x91, 0xab, 0x89, 0x87, 0xf1, 0x6c, 0xad, 0xa4, 0x81, 0x0f, 0x36, 0x07, 0x2a,
0x3a, 0x07, 0x22, 0xba, 0x56, 0xef, 0x30, 0xd8, 0xaa, 0xe0, 0x17, 0xe8, 0xee, 0xa5, 0xe4, 0xb3, 0x47, 0x68, 0x7c, 0x1c, 0xed, 0x4d, 0xc8, 0x1b, 0xfc, 0xf0, 0x4a, 0x89, 0xd5, 0x95, 0xd2, 0x92,
0x4b, 0x99, 0x0a, 0x12, 0xd5, 0x5d, 0xbf, 0xb3, 0x5a, 0xb8, 0x0f, 0x9a, 0x6f, 0x80, 0xe4, 0x33, 0x26, 0xcd, 0x36, 0x1c, 0xd6, 0x5b, 0xff, 0x49, 0xfb, 0x0d, 0x50, 0x62, 0xc5, 0x40, 0x69, 0x19,
0x0a, 0x32, 0x15, 0x5e, 0xb0, 0xa1, 0xf0, 0x00, 0x1d, 0x9d, 0x2b, 0x09, 0xef, 0x64, 0x2a, 0x81, 0x44, 0x1d, 0x45, 0xa6, 0xf8, 0xe4, 0xc2, 0x28, 0x78, 0xaf, 0xb4, 0x02, 0x9a, 0x3a, 0xe5, 0x79,
0xc4, 0x46, 0x79, 0xbc, 0x5a, 0xb8, 0x0f, 0x1b, 0x45, 0x2a, 0x09, 0x34, 0xa9, 0x7b, 0x5e, 0xd0, 0xbd, 0xf5, 0x9f, 0xb6, 0x8a, 0x32, 0x0a, 0xd8, 0xba, 0xd9, 0x05, 0x51, 0xcf, 0x35, 0xd2, 0xa7,
0x72, 0xb5, 0xf4, 0x71, 0xae, 0x78, 0x23, 0x4d, 0xfe, 0x95, 0x8a, 0xb9, 0xe2, 0x1b, 0x69, 0xc3, 0x8d, 0x11, 0xad, 0x74, 0xfd, 0xb7, 0x54, 0x6c, 0x8c, 0xe8, 0xa4, 0x8e, 0x73, 0x92, 0xe1, 0xd9,
0x19, 0x49, 0xb1, 0x6c, 0xa8, 0x4b, 0x05, 0x44, 0xfe, 0x27, 0x29, 0x96, 0x51, 0x5e, 0xf7, 0x6a, 0xcc, 0x96, 0x06, 0xa8, 0xfa, 0x47, 0x32, 0x3c, 0x63, 0xa2, 0xd9, 0x35, 0xd2, 0x1d, 0x47, 0x3e,
0x69, 0xcd, 0xe1, 0x4f, 0xa8, 0x33, 0x62, 0x55, 0xf3, 0x87, 0x43, 0xad, 0x94, 0xe0, 0x20, 0xb5, 0xe3, 0xe1, 0x9c, 0x57, 0xed, 0x1f, 0xce, 0xac, 0x31, 0x52, 0x80, 0xb2, 0xa6, 0xa0, 0x4b, 0xe7,
0x2a, 0xc8, 0xd4, 0xf8, 0x5b, 0x7b, 0xab, 0x77, 0xc5, 0x0d, 0x46, 0x79, 0xcb, 0x79, 0xc1, 0x4e, 0xef, 0xdd, 0xad, 0xb9, 0x95, 0x70, 0x18, 0x13, 0x3d, 0x17, 0x44, 0x07, 0xf5, 0x70, 0x78, 0xfb,
0xdd, 0xfb, 0x61, 0xa3, 0xe3, 0x5d, 0x41, 0x79, 0x4d, 0x5f, 0x52, 0x96, 0x64, 0x13, 0xb6, 0x8f, 0xcb, 0x3b, 0xba, 0xdd, 0x79, 0xe8, 0xc7, 0xce, 0x43, 0x3f, 0x77, 0x1e, 0xfa, 0xf6, 0xdb, 0x3b,
0xcb, 0x3e, 0x2e, 0x6d, 0xf9, 0xbb, 0x8d, 0x9e, 0xed, 0x8e, 0xcb, 0x80, 0x86, 0x02, 0xf6, 0x69, 0x8a, 0xef, 0xbb, 0xa7, 0x34, 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0x63, 0xdf, 0x89, 0x1b, 0xa8,
0xd9, 0xa7, 0xa5, 0x2d, 0xfb, 0x9d, 0xeb, 0xdf, 0xce, 0xc1, 0xf5, 0xd2, 0xb1, 0x7e, 0x2e, 0x1d, 0x02, 0x00, 0x00,
0xeb, 0xd7, 0xd2, 0xb1, 0xbe, 0xfe, 0x71, 0x0e, 0xc2, 0xdb, 0xe6, 0x89, 0x1a, 0xfc, 0x0d, 0x00,
0x00, 0xff, 0xff, 0xff, 0x80, 0x50, 0x7f, 0x00, 0x07, 0x00, 0x00,
} }

View File

@ -8,70 +8,6 @@ option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true; option (gogoproto.unmarshaler_all) = true;
option (gogoproto.goproto_getters_all) = false; option (gogoproto.goproto_getters_all) = false;
message flag__zookeeper__r3_4_9 {
// JavaDJuteMaxBuffer is for '-Djute.maxbuffer' flag.
// It is the maximum size, in bytes, of a request or response.
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#Unsafe+Options for more.
uint64 JavaDJuteMaxBuffer = 1 [(gogoproto.moretags) = "yaml:\"java_d_jute_max_buffer\""];
// JavaXms is for '-Xms' flag (minimum Java heap size).
// See https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html for more.
string JavaXms = 2 [(gogoproto.moretags) = "yaml:\"java_xms\""];
// JavaXmx is for '-Xmx' flag (maximum Java heap size).
// See https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html for more.
string JavaXmx = 3 [(gogoproto.moretags) = "yaml:\"java_xmx\""];
// MyID contains a single integer in human readable ASCII text that represents the server id.
// Each ZooKeeper server has a unique id. This id is used in two places: the myid file and the
// configuration file. The myid file identifies the server that corresponds to the given data directory.
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#sc_dataFileManagement for more.
uint32 MyID = 100;
// ClientPort is by default '2181'.
// No need to set manually. Inherited from 'database_port_to_connect'.
int64 ClientPort = 101;
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html for more.
int64 TickTime = 102 [(gogoproto.moretags) = "yaml:\"tick_time\""];
int64 InitLimit = 103 [(gogoproto.moretags) = "yaml:\"init_limit\""];
int64 SyncLimit = 104 [(gogoproto.moretags) = "yaml:\"sync_limit\""];
int64 SnapCount = 105 [(gogoproto.moretags) = "yaml:\"snap_count\""];
int64 MaxClientConnections = 106 [(gogoproto.moretags) = "yaml:\"max_client_connections\""];
}
message flag__zookeeper__r3_5_2_alpha {
// JavaDJuteMaxBuffer is for '-Djute.maxbuffer' flag.
// It is the maximum size, in bytes, of a request or response.
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#Unsafe+Options for more.
uint64 JavaDJuteMaxBuffer = 1 [(gogoproto.moretags) = "yaml:\"java_d_jute_max_buffer\""];
// JavaXms is for '-Xms' flag (minimum Java heap size).
// See https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html for more.
string JavaXms = 2 [(gogoproto.moretags) = "yaml:\"java_xms\""];
// JavaXmx is for '-Xmx' flag (maximum Java heap size).
// See https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html for more.
string JavaXmx = 3 [(gogoproto.moretags) = "yaml:\"java_xmx\""];
// MyID contains a single integer in human readable ASCII text that represents the server id.
// Each ZooKeeper server has a unique id. This id is used in two places: the myid file and the
// configuration file. The myid file identifies the server that corresponds to the given data directory.
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#sc_dataFileManagement for more.
uint32 MyID = 100;
// ClientPort is by default '2181'.
// No need to set manually. Inherited from 'database_port_to_connect'.
int64 ClientPort = 101;
// See http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html for more.
int64 TickTime = 102 [(gogoproto.moretags) = "yaml:\"tick_time\""];
int64 InitLimit = 103 [(gogoproto.moretags) = "yaml:\"init_limit\""];
int64 SyncLimit = 104 [(gogoproto.moretags) = "yaml:\"sync_limit\""];
int64 SnapCount = 105 [(gogoproto.moretags) = "yaml:\"snap_count\""];
int64 MaxClientConnections = 106 [(gogoproto.moretags) = "yaml:\"max_client_connections\""];
}
message flag__zookeeper__r3_5_3_beta { message flag__zookeeper__r3_5_3_beta {
// JavaDJuteMaxBuffer is for '-Djute.maxbuffer' flag. // JavaDJuteMaxBuffer is for '-Djute.maxbuffer' flag.
// It is the maximum size, in bytes, of a request or response. // It is the maximum size, in bytes, of a request or response.

View File

@ -8,10 +8,8 @@ import fmt "fmt"
import math "math" import math "math"
import _ "github.com/gogo/protobuf/gogoproto" import _ "github.com/gogo/protobuf/gogoproto"
import ( import context "golang.org/x/net/context"
context "golang.org/x/net/context" import grpc "google.golang.org/grpc"
grpc "google.golang.org/grpc"
)
import io "io" import io "io"
@ -56,16 +54,11 @@ type Request struct {
IPIndex uint32 `protobuf:"varint,6,opt,name=IPIndex,proto3" json:"IPIndex,omitempty"` IPIndex uint32 `protobuf:"varint,6,opt,name=IPIndex,proto3" json:"IPIndex,omitempty"`
CurrentClientNumber int64 `protobuf:"varint,7,opt,name=CurrentClientNumber,proto3" json:"CurrentClientNumber,omitempty"` CurrentClientNumber int64 `protobuf:"varint,7,opt,name=CurrentClientNumber,proto3" json:"CurrentClientNumber,omitempty"`
ConfigClientMachineInitial *ConfigClientMachineInitial `protobuf:"bytes,8,opt,name=ConfigClientMachineInitial" json:"ConfigClientMachineInitial,omitempty"` ConfigClientMachineInitial *ConfigClientMachineInitial `protobuf:"bytes,8,opt,name=ConfigClientMachineInitial" json:"ConfigClientMachineInitial,omitempty"`
Flag_Etcd_V2_3 *Flag_Etcd_V2_3 `protobuf:"bytes,100,opt,name=flag__etcd__v2_3,json=flagEtcdV23" json:"flag__etcd__v2_3,omitempty"` Flag_Etcd_Tip *Flag_Etcd_Tip `protobuf:"bytes,100,opt,name=flag__etcd__tip,json=flagEtcdTip" json:"flag__etcd__tip,omitempty"`
Flag_Etcd_V3_1 *Flag_Etcd_V3_1 `protobuf:"bytes,101,opt,name=flag__etcd__v3_1,json=flagEtcdV31" json:"flag__etcd__v3_1,omitempty"` Flag_Etcd_V3_2 *Flag_Etcd_V3_2 `protobuf:"bytes,101,opt,name=flag__etcd__v3_2,json=flagEtcdV32" json:"flag__etcd__v3_2,omitempty"`
Flag_Etcd_V3_2 *Flag_Etcd_V3_2 `protobuf:"bytes,102,opt,name=flag__etcd__v3_2,json=flagEtcdV32" json:"flag__etcd__v3_2,omitempty"` Flag_Etcd_V3_3 *Flag_Etcd_V3_3 `protobuf:"bytes,102,opt,name=flag__etcd__v3_3,json=flagEtcdV33" json:"flag__etcd__v3_3,omitempty"`
Flag_Etcd_Tip *Flag_Etcd_Tip `protobuf:"bytes,103,opt,name=flag__etcd__tip,json=flagEtcdTip" json:"flag__etcd__tip,omitempty"` Flag_Zookeeper_R3_5_3Beta *Flag_Zookeeper_R3_5_3Beta `protobuf:"bytes,200,opt,name=flag__zookeeper__r3_5_3_beta,json=flagZookeeperR353Beta" json:"flag__zookeeper__r3_5_3_beta,omitempty"`
Flag_Zookeeper_R3_4_9 *Flag_Zookeeper_R3_4_9 `protobuf:"bytes,200,opt,name=flag__zookeeper__r3_4_9,json=flagZookeeperR349" json:"flag__zookeeper__r3_4_9,omitempty"` Flag_Consul_V1_0_2 *Flag_Consul_V1_0_2 `protobuf:"bytes,300,opt,name=flag__consul__v1_0_2,json=flagConsulV102" json:"flag__consul__v1_0_2,omitempty"`
Flag_Zookeeper_R3_5_2Alpha *Flag_Zookeeper_R3_5_2Alpha `protobuf:"bytes,201,opt,name=flag__zookeeper__r3_5_2_alpha,json=flagZookeeperR352Alpha" json:"flag__zookeeper__r3_5_2_alpha,omitempty"`
Flag_Zookeeper_R3_5_3Beta *Flag_Zookeeper_R3_5_3Beta `protobuf:"bytes,202,opt,name=flag__zookeeper__r3_5_3_beta,json=flagZookeeperR353Beta" json:"flag__zookeeper__r3_5_3_beta,omitempty"`
Flag_Consul_V0_7_5 *Flag_Consul_V0_7_5 `protobuf:"bytes,300,opt,name=flag__consul__v0_7_5,json=flagConsulV075" json:"flag__consul__v0_7_5,omitempty"`
Flag_Consul_V0_8_0 *Flag_Consul_V0_8_0 `protobuf:"bytes,301,opt,name=flag__consul__v0_8_0,json=flagConsulV080" json:"flag__consul__v0_8_0,omitempty"`
Flag_Consul_V0_8_4 *Flag_Consul_V0_8_4 `protobuf:"bytes,302,opt,name=flag__consul__v0_8_4,json=flagConsulV084" json:"flag__consul__v0_8_4,omitempty"`
Flag_Cetcd_Beta *Flag_Cetcd_Beta `protobuf:"bytes,400,opt,name=flag__cetcd__beta,json=flagCetcdBeta" json:"flag__cetcd__beta,omitempty"` Flag_Cetcd_Beta *Flag_Cetcd_Beta `protobuf:"bytes,400,opt,name=flag__cetcd__beta,json=flagCetcdBeta" json:"flag__cetcd__beta,omitempty"`
Flag_Zetcd_Beta *Flag_Zetcd_Beta `protobuf:"bytes,500,opt,name=flag__zetcd__beta,json=flagZetcdBeta" json:"flag__zetcd__beta,omitempty"` Flag_Zetcd_Beta *Flag_Zetcd_Beta `protobuf:"bytes,500,opt,name=flag__zetcd__beta,json=flagZetcdBeta" json:"flag__zetcd__beta,omitempty"`
} }
@ -232,125 +225,65 @@ func (m *Request) MarshalTo(dAtA []byte) (int, error) {
} }
i += n1 i += n1
} }
if m.Flag_Etcd_V2_3 != nil { if m.Flag_Etcd_Tip != nil {
dAtA[i] = 0xa2 dAtA[i] = 0xa2
i++ i++
dAtA[i] = 0x6 dAtA[i] = 0x6
i++ i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Etcd_V2_3.Size())) i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Etcd_Tip.Size()))
n2, err := m.Flag_Etcd_V2_3.MarshalTo(dAtA[i:]) n2, err := m.Flag_Etcd_Tip.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n2 i += n2
} }
if m.Flag_Etcd_V3_1 != nil { if m.Flag_Etcd_V3_2 != nil {
dAtA[i] = 0xaa dAtA[i] = 0xaa
i++ i++
dAtA[i] = 0x6 dAtA[i] = 0x6
i++ i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Etcd_V3_1.Size())) i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Etcd_V3_2.Size()))
n3, err := m.Flag_Etcd_V3_1.MarshalTo(dAtA[i:]) n3, err := m.Flag_Etcd_V3_2.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n3 i += n3
} }
if m.Flag_Etcd_V3_2 != nil { if m.Flag_Etcd_V3_3 != nil {
dAtA[i] = 0xb2 dAtA[i] = 0xb2
i++ i++
dAtA[i] = 0x6 dAtA[i] = 0x6
i++ i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Etcd_V3_2.Size())) i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Etcd_V3_3.Size()))
n4, err := m.Flag_Etcd_V3_2.MarshalTo(dAtA[i:]) n4, err := m.Flag_Etcd_V3_3.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n4 i += n4
} }
if m.Flag_Etcd_Tip != nil { if m.Flag_Zookeeper_R3_5_3Beta != nil {
dAtA[i] = 0xba dAtA[i] = 0xc2
i++ i++
dAtA[i] = 0x6 dAtA[i] = 0xc
i++ i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Etcd_Tip.Size())) i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Zookeeper_R3_5_3Beta.Size()))
n5, err := m.Flag_Etcd_Tip.MarshalTo(dAtA[i:]) n5, err := m.Flag_Zookeeper_R3_5_3Beta.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n5 i += n5
} }
if m.Flag_Zookeeper_R3_4_9 != nil { if m.Flag_Consul_V1_0_2 != nil {
dAtA[i] = 0xc2
i++
dAtA[i] = 0xc
i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Zookeeper_R3_4_9.Size()))
n6, err := m.Flag_Zookeeper_R3_4_9.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n6
}
if m.Flag_Zookeeper_R3_5_2Alpha != nil {
dAtA[i] = 0xca
i++
dAtA[i] = 0xc
i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Zookeeper_R3_5_2Alpha.Size()))
n7, err := m.Flag_Zookeeper_R3_5_2Alpha.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n7
}
if m.Flag_Zookeeper_R3_5_3Beta != nil {
dAtA[i] = 0xd2
i++
dAtA[i] = 0xc
i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Zookeeper_R3_5_3Beta.Size()))
n8, err := m.Flag_Zookeeper_R3_5_3Beta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n8
}
if m.Flag_Consul_V0_7_5 != nil {
dAtA[i] = 0xe2 dAtA[i] = 0xe2
i++ i++
dAtA[i] = 0x12 dAtA[i] = 0x12
i++ i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Consul_V0_7_5.Size())) i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Consul_V1_0_2.Size()))
n9, err := m.Flag_Consul_V0_7_5.MarshalTo(dAtA[i:]) n6, err := m.Flag_Consul_V1_0_2.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n9 i += n6
}
if m.Flag_Consul_V0_8_0 != nil {
dAtA[i] = 0xea
i++
dAtA[i] = 0x12
i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Consul_V0_8_0.Size()))
n10, err := m.Flag_Consul_V0_8_0.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n10
}
if m.Flag_Consul_V0_8_4 != nil {
dAtA[i] = 0xf2
i++
dAtA[i] = 0x12
i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Consul_V0_8_4.Size()))
n11, err := m.Flag_Consul_V0_8_4.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n11
} }
if m.Flag_Cetcd_Beta != nil { if m.Flag_Cetcd_Beta != nil {
dAtA[i] = 0x82 dAtA[i] = 0x82
@ -358,11 +291,11 @@ func (m *Request) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x19 dAtA[i] = 0x19
i++ i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Cetcd_Beta.Size())) i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Cetcd_Beta.Size()))
n12, err := m.Flag_Cetcd_Beta.MarshalTo(dAtA[i:]) n7, err := m.Flag_Cetcd_Beta.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n12 i += n7
} }
if m.Flag_Zetcd_Beta != nil { if m.Flag_Zetcd_Beta != nil {
dAtA[i] = 0xa2 dAtA[i] = 0xa2
@ -370,11 +303,11 @@ func (m *Request) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x1f dAtA[i] = 0x1f
i++ i++
i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Zetcd_Beta.Size())) i = encodeVarintMessage(dAtA, i, uint64(m.Flag_Zetcd_Beta.Size()))
n13, err := m.Flag_Zetcd_Beta.MarshalTo(dAtA[i:]) n8, err := m.Flag_Zetcd_Beta.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n13 i += n8
} }
return i, nil return i, nil
} }
@ -412,24 +345,6 @@ func (m *Response) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func encodeFixed64Message(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Message(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintMessage(dAtA []byte, offset int, v uint64) int { func encodeVarintMessage(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)
@ -469,44 +384,24 @@ func (m *Request) Size() (n int) {
l = m.ConfigClientMachineInitial.Size() l = m.ConfigClientMachineInitial.Size()
n += 1 + l + sovMessage(uint64(l)) n += 1 + l + sovMessage(uint64(l))
} }
if m.Flag_Etcd_V2_3 != nil { if m.Flag_Etcd_Tip != nil {
l = m.Flag_Etcd_V2_3.Size() l = m.Flag_Etcd_Tip.Size()
n += 2 + l + sovMessage(uint64(l))
}
if m.Flag_Etcd_V3_1 != nil {
l = m.Flag_Etcd_V3_1.Size()
n += 2 + l + sovMessage(uint64(l)) n += 2 + l + sovMessage(uint64(l))
} }
if m.Flag_Etcd_V3_2 != nil { if m.Flag_Etcd_V3_2 != nil {
l = m.Flag_Etcd_V3_2.Size() l = m.Flag_Etcd_V3_2.Size()
n += 2 + l + sovMessage(uint64(l)) n += 2 + l + sovMessage(uint64(l))
} }
if m.Flag_Etcd_Tip != nil { if m.Flag_Etcd_V3_3 != nil {
l = m.Flag_Etcd_Tip.Size() l = m.Flag_Etcd_V3_3.Size()
n += 2 + l + sovMessage(uint64(l))
}
if m.Flag_Zookeeper_R3_4_9 != nil {
l = m.Flag_Zookeeper_R3_4_9.Size()
n += 2 + l + sovMessage(uint64(l))
}
if m.Flag_Zookeeper_R3_5_2Alpha != nil {
l = m.Flag_Zookeeper_R3_5_2Alpha.Size()
n += 2 + l + sovMessage(uint64(l)) n += 2 + l + sovMessage(uint64(l))
} }
if m.Flag_Zookeeper_R3_5_3Beta != nil { if m.Flag_Zookeeper_R3_5_3Beta != nil {
l = m.Flag_Zookeeper_R3_5_3Beta.Size() l = m.Flag_Zookeeper_R3_5_3Beta.Size()
n += 2 + l + sovMessage(uint64(l)) n += 2 + l + sovMessage(uint64(l))
} }
if m.Flag_Consul_V0_7_5 != nil { if m.Flag_Consul_V1_0_2 != nil {
l = m.Flag_Consul_V0_7_5.Size() l = m.Flag_Consul_V1_0_2.Size()
n += 2 + l + sovMessage(uint64(l))
}
if m.Flag_Consul_V0_8_0 != nil {
l = m.Flag_Consul_V0_8_0.Size()
n += 2 + l + sovMessage(uint64(l))
}
if m.Flag_Consul_V0_8_4 != nil {
l = m.Flag_Consul_V0_8_4.Size()
n += 2 + l + sovMessage(uint64(l)) n += 2 + l + sovMessage(uint64(l))
} }
if m.Flag_Cetcd_Beta != nil { if m.Flag_Cetcd_Beta != nil {
@ -763,7 +658,7 @@ func (m *Request) Unmarshal(dAtA []byte) error {
iNdEx = postIndex iNdEx = postIndex
case 100: case 100:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V2_3", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_Tip", wireType)
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -787,47 +682,14 @@ func (m *Request) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if m.Flag_Etcd_V2_3 == nil { if m.Flag_Etcd_Tip == nil {
m.Flag_Etcd_V2_3 = &Flag_Etcd_V2_3{} m.Flag_Etcd_Tip = &Flag_Etcd_Tip{}
} }
if err := m.Flag_Etcd_V2_3.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Flag_Etcd_Tip.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 101: case 101:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V3_1", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMessage
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Etcd_V3_1 == nil {
m.Flag_Etcd_V3_1 = &Flag_Etcd_V3_1{}
}
if err := m.Flag_Etcd_V3_1.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 102:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V3_2", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V3_2", wireType)
} }
@ -860,9 +722,9 @@ func (m *Request) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 103: case 102:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_Tip", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Etcd_V3_3", wireType)
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -886,80 +748,14 @@ func (m *Request) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if m.Flag_Etcd_Tip == nil { if m.Flag_Etcd_V3_3 == nil {
m.Flag_Etcd_Tip = &Flag_Etcd_Tip{} m.Flag_Etcd_V3_3 = &Flag_Etcd_V3_3{}
} }
if err := m.Flag_Etcd_Tip.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Flag_Etcd_V3_3.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 200: case 200:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Zookeeper_R3_4_9", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMessage
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Zookeeper_R3_4_9 == nil {
m.Flag_Zookeeper_R3_4_9 = &Flag_Zookeeper_R3_4_9{}
}
if err := m.Flag_Zookeeper_R3_4_9.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 201:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Zookeeper_R3_5_2Alpha", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMessage
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Zookeeper_R3_5_2Alpha == nil {
m.Flag_Zookeeper_R3_5_2Alpha = &Flag_Zookeeper_R3_5_2Alpha{}
}
if err := m.Flag_Zookeeper_R3_5_2Alpha.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 202:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Zookeeper_R3_5_3Beta", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Zookeeper_R3_5_3Beta", wireType)
} }
@ -994,7 +790,7 @@ func (m *Request) Unmarshal(dAtA []byte) error {
iNdEx = postIndex iNdEx = postIndex
case 300: case 300:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Consul_V0_7_5", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Flag_Consul_V1_0_2", wireType)
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -1018,76 +814,10 @@ func (m *Request) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if m.Flag_Consul_V0_7_5 == nil { if m.Flag_Consul_V1_0_2 == nil {
m.Flag_Consul_V0_7_5 = &Flag_Consul_V0_7_5{} m.Flag_Consul_V1_0_2 = &Flag_Consul_V1_0_2{}
} }
if err := m.Flag_Consul_V0_7_5.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Flag_Consul_V1_0_2.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 301:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Consul_V0_8_0", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMessage
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Consul_V0_8_0 == nil {
m.Flag_Consul_V0_8_0 = &Flag_Consul_V0_8_0{}
}
if err := m.Flag_Consul_V0_8_0.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 302:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Flag_Consul_V0_8_4", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMessage
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Flag_Consul_V0_8_4 == nil {
m.Flag_Consul_V0_8_4 = &Flag_Consul_V0_8_4{}
}
if err := m.Flag_Consul_V0_8_4.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
@ -1375,55 +1105,49 @@ var (
func init() { proto.RegisterFile("dbtesterpb/message.proto", fileDescriptorMessage) } func init() { proto.RegisterFile("dbtesterpb/message.proto", fileDescriptorMessage) }
var fileDescriptorMessage = []byte{ var fileDescriptorMessage = []byte{
// 787 bytes of a gzipped FileDescriptorProto // 690 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x95, 0x5f, 0x4e, 0xeb, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0x51, 0x4e, 0x1b, 0x3b,
0x14, 0xc6, 0x63, 0x72, 0xef, 0x25, 0x99, 0x28, 0xb7, 0xb9, 0x73, 0x81, 0x8e, 0x02, 0xa4, 0x16, 0x14, 0x86, 0x33, 0x04, 0x48, 0xe2, 0x28, 0xdc, 0x5c, 0x03, 0x57, 0x56, 0xe0, 0xa6, 0x23, 0x54,
0xad, 0x50, 0x8a, 0xd4, 0x24, 0xd8, 0x49, 0x81, 0x47, 0x08, 0xad, 0x88, 0xd4, 0x16, 0x34, 0x09, 0xa1, 0x08, 0xa9, 0x09, 0x64, 0x44, 0xfb, 0x5c, 0x42, 0x2b, 0x22, 0xb5, 0x05, 0x39, 0x81, 0x07,
0xa8, 0xe2, 0x65, 0x34, 0x76, 0x26, 0xc6, 0x22, 0xb1, 0xdd, 0xf1, 0x04, 0xb5, 0xac, 0xa2, 0x8f, 0x5e, 0x2c, 0xcf, 0xe4, 0x64, 0x18, 0x91, 0x8c, 0xa7, 0x1e, 0x07, 0xb5, 0xac, 0xa2, 0x8f, 0x5d,
0x5d, 0x44, 0xdb, 0x75, 0xd0, 0x3e, 0x75, 0x09, 0x2d, 0xed, 0x12, 0xba, 0x80, 0xca, 0xe3, 0xfc, 0x44, 0x17, 0xd0, 0x25, 0xf0, 0xd8, 0x25, 0xb4, 0x74, 0x0b, 0x5d, 0x40, 0x35, 0x9e, 0x84, 0x18,
0x99, 0x24, 0x4e, 0xc3, 0x1b, 0xe7, 0xfb, 0xbe, 0xf3, 0x3b, 0xf2, 0xc1, 0x39, 0x06, 0xa8, 0x6b, 0x12, 0xda, 0xb7, 0x9c, 0xff, 0xff, 0xfd, 0x8d, 0x7d, 0x62, 0x1f, 0x44, 0x7a, 0xae, 0x82, 0x58,
0x09, 0x16, 0x0a, 0xc6, 0x03, 0xab, 0x3a, 0x60, 0x61, 0x48, 0x1d, 0x56, 0x09, 0xb8, 0x2f, 0x7c, 0x81, 0x8c, 0xdc, 0xc6, 0x10, 0xe2, 0x98, 0xfb, 0x50, 0x8f, 0xa4, 0x50, 0x02, 0xa3, 0xa9, 0x53,
0x08, 0xa6, 0x4e, 0xf1, 0x33, 0xc7, 0x15, 0x77, 0x43, 0xab, 0x62, 0xfb, 0x83, 0xaa, 0xe3, 0x3b, 0x79, 0xe6, 0x07, 0xea, 0x62, 0xe4, 0xd6, 0x3d, 0x31, 0x6c, 0xf8, 0xc2, 0x17, 0x0d, 0x1d, 0x71,
0x7e, 0x55, 0x46, 0xac, 0x61, 0x4f, 0x56, 0xb2, 0x90, 0x7f, 0xc5, 0xad, 0xc5, 0x1d, 0x05, 0xda, 0x47, 0x7d, 0x5d, 0xe9, 0x42, 0xff, 0x4a, 0x97, 0x56, 0x36, 0x0d, 0x68, 0x8f, 0x2b, 0xee, 0xf2,
0xa5, 0x82, 0x5a, 0x34, 0x64, 0xc4, 0xed, 0x8e, 0xdc, 0xa2, 0xe2, 0xf6, 0xfa, 0xd4, 0x21, 0x4c, 0x18, 0x58, 0xd0, 0x1b, 0xbb, 0x15, 0xc3, 0xed, 0x0f, 0xb8, 0xcf, 0x40, 0x79, 0x13, 0xef, 0xc9,
0xd8, 0x63, 0xef, 0xa3, 0x79, 0xef, 0xd1, 0xf7, 0xef, 0x19, 0x0b, 0x18, 0x4f, 0x40, 0xcb, 0x80, 0x43, 0xef, 0x5a, 0x88, 0x4b, 0x80, 0x08, 0xe4, 0x1c, 0xb4, 0x0e, 0x78, 0x22, 0x8c, 0x47, 0x83,
0xed, 0x7b, 0xe1, 0xb0, 0x3f, 0x72, 0xb7, 0x17, 0xda, 0x15, 0xf6, 0x82, 0x69, 0x2b, 0xe6, 0xbe, 0xb1, 0xbb, 0x31, 0xb3, 0xdc, 0x60, 0xcf, 0x98, 0x9e, 0x61, 0x6e, 0x1b, 0xa6, 0x27, 0xc2, 0x7e,
0x62, 0xda, 0xbe, 0xd7, 0x73, 0x1d, 0x62, 0xf7, 0x5d, 0xe6, 0x09, 0x32, 0xa0, 0xf6, 0x9d, 0xeb, 0xe0, 0x33, 0x6f, 0x10, 0x40, 0xa8, 0xd8, 0x90, 0x7b, 0x17, 0x41, 0x38, 0xee, 0xca, 0xd6, 0xd7,
0x8d, 0xb6, 0xb2, 0xf7, 0x0f, 0x00, 0xeb, 0x98, 0x7d, 0x37, 0x64, 0xa1, 0x80, 0x26, 0xc8, 0x5e, 0x1c, 0xca, 0x51, 0x78, 0x3f, 0x82, 0x58, 0x61, 0x07, 0x15, 0x8e, 0x23, 0x90, 0x5c, 0x05, 0x22,
0x06, 0x8c, 0x53, 0xe1, 0xfa, 0x1e, 0xd2, 0x74, 0xad, 0xfc, 0xd6, 0xd8, 0xac, 0x4c, 0x39, 0x95, 0x24, 0x96, 0x6d, 0xd5, 0x56, 0x9a, 0xeb, 0xf5, 0x29, 0xa7, 0x7e, 0x67, 0xd2, 0x69, 0x0e, 0xef,
0x89, 0x89, 0xa7, 0x39, 0x78, 0x00, 0x0a, 0x1d, 0xee, 0x3a, 0x0e, 0xe3, 0x5f, 0xf9, 0xce, 0x75, 0xa0, 0x72, 0x57, 0x06, 0xbe, 0x0f, 0xf2, 0x8d, 0xf0, 0x4f, 0xa3, 0x81, 0xe0, 0x3d, 0xb2, 0x60,
0xd0, 0xf7, 0x69, 0x17, 0xad, 0xe9, 0x5a, 0x39, 0x83, 0x17, 0x74, 0xf8, 0x39, 0x00, 0xe7, 0xa3, 0x5b, 0xb5, 0x3c, 0x9d, 0xd1, 0xf1, 0x73, 0x84, 0x0e, 0xc7, 0xed, 0x6b, 0x1f, 0x92, 0xac, 0xfe,
0xf5, 0xb5, 0xce, 0x51, 0x5a, 0x4e, 0xd8, 0x52, 0x27, 0x4c, 0x5d, 0xac, 0x24, 0xa1, 0x0e, 0x72, 0xc2, 0x7f, 0xe6, 0x17, 0xa6, 0x2e, 0x35, 0x92, 0xd8, 0x46, 0xc5, 0x49, 0xd5, 0xe5, 0x3e, 0x59,
0xe3, 0xaa, 0x43, 0x1d, 0xf4, 0x4a, 0xd7, 0xca, 0x59, 0xac, 0x4a, 0xf0, 0x13, 0x90, 0xbf, 0x62, 0xb4, 0xad, 0x5a, 0x81, 0x9a, 0x12, 0x7e, 0x8a, 0x4a, 0x27, 0x00, 0xb2, 0x7d, 0x12, 0x77, 0x94,
0x8c, 0xb7, 0xae, 0xc2, 0xb6, 0xe0, 0xae, 0xe7, 0xa0, 0xd7, 0x32, 0x33, 0x2b, 0x42, 0x04, 0xd6, 0x0c, 0x42, 0x9f, 0x2c, 0xe9, 0xcc, 0x7d, 0x11, 0x13, 0x94, 0x6b, 0x9f, 0xb4, 0xc3, 0x1e, 0x7c,
0x5b, 0x57, 0x2d, 0xaf, 0xcb, 0xbe, 0x47, 0x6f, 0x74, 0xad, 0x9c, 0xc7, 0xe3, 0x12, 0xd6, 0xc0, 0x20, 0xcb, 0xb6, 0x55, 0x2b, 0xd1, 0x49, 0x89, 0x77, 0xd1, 0x6a, 0x6b, 0x24, 0x25, 0x84, 0xaa,
0xfb, 0xe6, 0x90, 0x73, 0xe6, 0x89, 0xa6, 0xdc, 0xd2, 0x37, 0xc3, 0x81, 0xc5, 0x38, 0x5a, 0xd7, 0xa5, 0xbb, 0xf4, 0x6e, 0x34, 0x74, 0x41, 0x92, 0x9c, 0x6d, 0xd5, 0xb2, 0x74, 0x9e, 0x85, 0xfb,
0xb5, 0x72, 0x1a, 0x27, 0x59, 0xb0, 0x07, 0x8a, 0x4d, 0xb9, 0xd7, 0x58, 0xfd, 0x3a, 0xde, 0x6a, 0xa8, 0xd2, 0xd2, 0x7d, 0x4d, 0xd5, 0xb7, 0x69, 0x57, 0xdb, 0x61, 0xa0, 0x02, 0x3e, 0x20, 0x79,
0xcb, 0x73, 0x85, 0x4b, 0xfb, 0x28, 0xa3, 0x6b, 0xe5, 0x9c, 0xb1, 0xaf, 0x3e, 0xdb, 0xf2, 0x34, 0xdb, 0xaa, 0x15, 0x9b, 0xdb, 0xe6, 0xd9, 0x1e, 0x4f, 0xd3, 0x3f, 0x90, 0xf0, 0x4b, 0xf4, 0x8f,
0xfe, 0x1f, 0x12, 0x6c, 0x82, 0x82, 0xfc, 0xe7, 0xca, 0xb7, 0x8a, 0x90, 0x07, 0x83, 0x98, 0xa8, 0xfe, 0x73, 0xf5, 0xad, 0x62, 0x4c, 0x05, 0x11, 0xe9, 0x69, 0xf8, 0x86, 0x09, 0x7f, 0x10, 0xa1,
0x2b, 0xe9, 0x3b, 0x2a, 0x7d, 0x3e, 0x83, 0x73, 0x91, 0xf2, 0x85, 0xb0, 0xbb, 0x37, 0x86, 0xb9, 0xc5, 0x44, 0x78, 0xa5, 0xbc, 0x5e, 0x37, 0x88, 0x70, 0x0b, 0x95, 0x4d, 0xff, 0xca, 0x61, 0x4d,
0x00, 0x31, 0xc9, 0x21, 0x62, 0x2b, 0x20, 0x26, 0x39, 0x54, 0x20, 0xe6, 0x61, 0x02, 0xc4, 0x40, 0x02, 0x9a, 0xb1, 0xf9, 0x18, 0x23, 0xc9, 0x4c, 0x21, 0x67, 0x4e, 0x73, 0x0e, 0xc4, 0x21, 0xfd,
0xbd, 0x95, 0x10, 0x43, 0x85, 0x18, 0xf0, 0x14, 0x7c, 0xa0, 0x06, 0x84, 0x1b, 0x20, 0x47, 0x32, 0xbf, 0x42, 0x1c, 0x13, 0xe2, 0xe0, 0x3e, 0xda, 0x4c, 0x03, 0x77, 0xcf, 0x80, 0x31, 0xe9, 0xb0,
0xb6, 0x97, 0x31, 0x84, 0x1b, 0x4c, 0x11, 0x1d, 0x37, 0x80, 0xdf, 0x82, 0x0f, 0x63, 0x7f, 0xf2, 0x7d, 0xe6, 0x30, 0x17, 0x14, 0x27, 0x37, 0x96, 0x26, 0xd6, 0x66, 0x89, 0xf3, 0x17, 0xd0, 0xf5,
0x5b, 0x22, 0x84, 0x9b, 0xa4, 0x4e, 0x4e, 0xd0, 0x93, 0x26, 0x59, 0x1f, 0x2f, 0xb2, 0x16, 0xb2, 0xc4, 0x3d, 0x9f, 0x78, 0xd4, 0xd9, 0x77, 0x0e, 0x40, 0x71, 0x7c, 0x8c, 0xd6, 0xd2, 0x65, 0xe9,
0xf8, 0x5d, 0x64, 0xdc, 0x8e, 0x65, 0x6c, 0xd6, 0x4f, 0xa0, 0x0b, 0x76, 0x93, 0xd2, 0x0d, 0x62, 0x6b, 0x62, 0xec, 0x6a, 0x8f, 0xed, 0xb2, 0x26, 0xf9, 0xb2, 0xa0, 0xf9, 0xf6, 0x2c, 0xff, 0x7e,
0x10, 0xda, 0x0f, 0xee, 0x28, 0xfa, 0x2d, 0xe6, 0x7f, 0xba, 0x8a, 0x3f, 0xe9, 0xc0, 0x5b, 0x73, 0x90, 0xae, 0x24, 0x6a, 0x4b, 0x6b, 0x67, 0x7b, 0xbb, 0x4d, 0x7c, 0x84, 0xfe, 0x1d, 0xe7, 0xd2,
0x53, 0x1a, 0xc6, 0x69, 0xa4, 0xc3, 0x1e, 0xd8, 0x49, 0x6e, 0x34, 0x89, 0xc5, 0x04, 0x45, 0xbf, 0xa3, 0xe9, 0xdd, 0x7e, 0xca, 0x6a, 0xda, 0xff, 0x73, 0x68, 0xd3, 0x14, 0x2d, 0x69, 0x54, 0x22,
0xc7, 0x93, 0xca, 0xab, 0x27, 0xc5, 0x0d, 0x78, 0x73, 0x7e, 0x90, 0x79, 0xc6, 0x04, 0x85, 0x97, 0xe8, 0xad, 0xdd, 0x91, 0xae, 0x0d, 0xd2, 0xaf, 0x47, 0x49, 0xd7, 0x0f, 0x49, 0xe7, 0x13, 0xd2,
0x60, 0x23, 0x6e, 0x8b, 0xef, 0x0a, 0x21, 0x0f, 0x35, 0x72, 0x44, 0x1a, 0xe8, 0xe7, 0x35, 0xc9, 0xd6, 0x19, 0xca, 0x53, 0x88, 0x23, 0x11, 0xc6, 0x90, 0xdc, 0xec, 0xce, 0xc8, 0xf3, 0x20, 0x8e,
0xd7, 0x17, 0xf9, 0xb3, 0x41, 0xfc, 0x36, 0x52, 0x9b, 0x52, 0xbb, 0xa9, 0x1d, 0x35, 0x12, 0x81, 0xf5, 0xc3, 0xcd, 0xd3, 0x49, 0x99, 0xdc, 0xec, 0xc3, 0x20, 0xbe, 0xec, 0x44, 0xdc, 0x83, 0xd3,
0xc7, 0xa4, 0x86, 0x7e, 0x79, 0x09, 0xf0, 0x98, 0xd4, 0x66, 0x81, 0xc7, 0xb5, 0x25, 0xc0, 0x3a, 0x64, 0x1c, 0x1e, 0x7c, 0x54, 0x10, 0xeb, 0x27, 0x9a, 0xa5, 0xf3, 0xac, 0x9d, 0x86, 0x31, 0x06,
0xfa, 0xf5, 0x65, 0xc0, 0xfa, 0x1c, 0xb0, 0x0e, 0x2f, 0xc0, 0xbb, 0x51, 0x2e, 0x7e, 0x81, 0xe4, 0x70, 0x01, 0x2d, 0x75, 0x14, 0x97, 0xaa, 0x9c, 0xc1, 0x79, 0xb4, 0xd8, 0x51, 0x22, 0x2a, 0x5b,
0x3e, 0x7f, 0x4c, 0x4b, 0xda, 0x6e, 0x02, 0x6d, 0x9a, 0xc2, 0x79, 0x89, 0x8a, 0x04, 0xb9, 0xbc, 0xb8, 0x84, 0x0a, 0x47, 0xc0, 0xa5, 0x72, 0x81, 0xab, 0xf2, 0x42, 0xf3, 0x35, 0x2a, 0x76, 0x25,
0x09, 0xe9, 0x51, 0x21, 0xfd, 0xbb, 0x94, 0xf4, 0x38, 0x4f, 0xba, 0x1d, 0x93, 0xf6, 0x6e, 0x40, 0x0f, 0xe3, 0x48, 0x48, 0x05, 0x12, 0xbf, 0x40, 0x79, 0x5d, 0xf6, 0x41, 0xe2, 0x55, 0xf3, 0x44,
0x06, 0xb3, 0x30, 0xf0, 0xbd, 0x90, 0x45, 0x57, 0xa8, 0x3d, 0xb4, 0x6d, 0x16, 0x86, 0xf2, 0xc8, 0xe3, 0x39, 0x53, 0x59, 0xbb, 0x2f, 0xa6, 0x47, 0xd8, 0xca, 0x1c, 0xac, 0xdd, 0xfc, 0xa8, 0x66,
0x66, 0xf0, 0xb8, 0x8c, 0xae, 0xd0, 0xb9, 0x1b, 0xde, 0xb7, 0x03, 0x6a, 0xb3, 0xeb, 0xe8, 0xd3, 0x6e, 0x6e, 0xab, 0xd6, 0xb7, 0xdb, 0xaa, 0xf5, 0xfd, 0xb6, 0x6a, 0x7d, 0xfe, 0x59, 0xcd, 0xb8,
0x75, 0xf6, 0x83, 0x60, 0xa1, 0x3c, 0xa7, 0x69, 0x9c, 0x64, 0x1d, 0x54, 0x95, 0x93, 0x0d, 0xb3, 0xcb, 0x7a, 0x50, 0x39, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x3f, 0xed, 0x0b, 0xe3, 0xda, 0x05,
0xe0, 0x75, 0x5b, 0x50, 0x2e, 0x0a, 0x29, 0x98, 0x01, 0xaf, 0xda, 0xc2, 0x0f, 0x0a, 0x1a, 0xcc, 0x00, 0x00,
0x83, 0xec, 0x05, 0xa3, 0x5c, 0x58, 0x8c, 0x8a, 0xc2, 0x9a, 0xf1, 0x25, 0xc8, 0x75, 0x38, 0xf5,
0xc2, 0xc0, 0xe7, 0x82, 0x71, 0x78, 0x04, 0x32, 0xb2, 0xec, 0x31, 0x0e, 0xdf, 0xab, 0x4f, 0x34,
0xfa, 0x26, 0x14, 0x37, 0x66, 0xc5, 0xf8, 0x11, 0xf6, 0x52, 0x67, 0x1b, 0x4f, 0x7f, 0x95, 0x52,
0x4f, 0xcf, 0x25, 0xed, 0x8f, 0xe7, 0x92, 0xf6, 0xe7, 0x73, 0x49, 0xfb, 0xe9, 0xef, 0x52, 0xca,
0x7a, 0x23, 0x3f, 0x2a, 0xe6, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x57, 0x68, 0x8f, 0x9f, 0x86,
0x07, 0x00, 0x00,
} }

View File

@ -45,18 +45,13 @@ message Request {
ConfigClientMachineInitial ConfigClientMachineInitial = 8; ConfigClientMachineInitial ConfigClientMachineInitial = 8;
flag__etcd__v2_3 flag__etcd__v2_3 = 100; flag__etcd__tip flag__etcd__tip = 100;
flag__etcd__v3_1 flag__etcd__v3_1 = 101; flag__etcd__v3_2 flag__etcd__v3_2 = 101;
flag__etcd__v3_2 flag__etcd__v3_2 = 102; flag__etcd__v3_3 flag__etcd__v3_3 = 102;
flag__etcd__tip flag__etcd__tip = 103;
flag__zookeeper__r3_4_9 flag__zookeeper__r3_4_9 = 200; flag__zookeeper__r3_5_3_beta flag__zookeeper__r3_5_3_beta = 200;
flag__zookeeper__r3_5_2_alpha flag__zookeeper__r3_5_2_alpha = 201;
flag__zookeeper__r3_5_3_beta flag__zookeeper__r3_5_3_beta = 202;
flag__consul__v0_7_5 flag__consul__v0_7_5 = 300; flag__consul__v1_0_2 flag__consul__v1_0_2 = 300;
flag__consul__v0_8_0 flag__consul__v0_8_0 = 301;
flag__consul__v0_8_4 flag__consul__v0_8_4 = 302;
flag__cetcd__beta flag__cetcd__beta = 400; flag__cetcd__beta flag__cetcd__beta = 400;
flag__zetcd__beta flag__zetcd__beta = 500; flag__zetcd__beta flag__zetcd__beta = 500;

View File

@ -18,7 +18,7 @@ import (
"image/color" "image/color"
"sort" "sort"
"github.com/gonum/plot/plotutil" "gonum.org/v1/plot/plotutil"
) )
// IsValidDatabaseID returns false if the database id is not supported. // IsValidDatabaseID returns false if the database id is not supported.
@ -39,21 +39,15 @@ func GetAllDatabaseIDs() []string {
func GetRGBI(databaseID string, i int) color.Color { func GetRGBI(databaseID string, i int) color.Color {
switch databaseID { switch databaseID {
case "etcd__v2_3":
return color.RGBA{218, 97, 229, 255} // purple
case "etcd__v3_1":
return color.RGBA{0, 229, 255, 255} // cyan
case "etcd__v3_2":
return color.RGBA{63, 81, 181, 255} // indigo
case "etcd__tip": case "etcd__tip":
return color.RGBA{24, 90, 169, 255} // blue return color.RGBA{24, 90, 169, 255} // blue
case "etcd__v3_2":
return color.RGBA{0, 229, 255, 255} // cyan
case "etcd__v3_3":
return color.RGBA{63, 81, 181, 255} // indigo
case "zookeeper__r3_5_3_beta": case "zookeeper__r3_5_3_beta":
return color.RGBA{94, 191, 30, 255} // green return color.RGBA{94, 191, 30, 255} // green
case "consul__v0_7_5": case "consul__v1_0_2":
return color.RGBA{198, 53, 53, 255} // red
case "consul__v0_8_0":
return color.RGBA{212, 88, 102, 255} // red
case "consul__v0_8_4":
return color.RGBA{254, 25, 102, 255} // red return color.RGBA{254, 25, 102, 255} // red
case "zetcd__beta": case "zetcd__beta":
return color.RGBA{251, 206, 0, 255} // yellow return color.RGBA{251, 206, 0, 255} // yellow
@ -65,21 +59,15 @@ func GetRGBI(databaseID string, i int) color.Color {
func GetRGBII(databaseID string, i int) color.Color { func GetRGBII(databaseID string, i int) color.Color {
switch databaseID { switch databaseID {
case "etcd__v2_3":
return color.RGBA{229, 212, 231, 255} // light-purple
case "etcd__v3_1":
return color.RGBA{132, 255, 255, 255} // light-cyan
case "etcd__v3_2":
return color.RGBA{159, 168, 218, 255} // light-indigo
case "etcd__tip": case "etcd__tip":
return color.RGBA{129, 212, 247, 255} // light-blue return color.RGBA{129, 212, 247, 255} // light-blue
case "etcd__v3_2":
return color.RGBA{132, 255, 255, 255} // light-cyan
case "etcd__v3_3":
return color.RGBA{159, 168, 218, 255} // light-indigo
case "zookeeper__r3_5_3_beta": case "zookeeper__r3_5_3_beta":
return color.RGBA{155, 176, 29, 255} // light-green return color.RGBA{155, 176, 29, 255} // light-green
case "consul__v0_7_5": case "consul__v1_0_2":
return color.RGBA{247, 156, 156, 255} // light-red
case "consul__v0_8_0":
return color.RGBA{238, 148, 178, 255} // light-red
case "consul__v0_8_4":
return color.RGBA{255, 202, 178, 255} // light-red return color.RGBA{255, 202, 178, 255} // light-red
case "zetcd__beta": case "zetcd__beta":
return color.RGBA{245, 247, 166, 255} // light-yellow return color.RGBA{245, 247, 166, 255} // light-yellow
@ -91,21 +79,15 @@ func GetRGBII(databaseID string, i int) color.Color {
func GetRGBIII(databaseID string, i int) color.Color { func GetRGBIII(databaseID string, i int) color.Color {
switch databaseID { switch databaseID {
case "etcd__v2_3":
return color.RGBA{165, 8, 180, 255} // deep-purple
case "etcd__v3_1":
return color.RGBA{0, 96, 100, 255} // deep-cyan
case "etcd__v3_2":
return color.RGBA{26, 35, 126, 255} // deep-indigo
case "etcd__tip": case "etcd__tip":
return color.RGBA{37, 29, 191, 255} // deep-blue return color.RGBA{37, 29, 191, 255} // deep-blue
case "etcd__v3_2":
return color.RGBA{0, 96, 100, 255} // deep-cyan
case "etcd__v3_3":
return color.RGBA{26, 35, 126, 255} // deep-indigo
case "zookeeper__r3_5_3_beta": case "zookeeper__r3_5_3_beta":
return color.RGBA{129, 210, 178, 255} // mid-cyan return color.RGBA{129, 210, 178, 255} // mid-cyan
case "consul__v0_7_5": case "consul__v1_0_2":
return color.RGBA{212, 8, 46, 255} // deep-red
case "consul__v0_8_0":
return color.RGBA{251, 110, 84, 255} // deep-red
case "consul__v0_8_4":
return color.RGBA{245, 144, 84, 255} // deep-red return color.RGBA{245, 144, 84, 255} // deep-red
case "zetcd__beta": case "zetcd__beta":
return color.RGBA{229, 255, 0, 255} // deep-yellow return color.RGBA{229, 255, 0, 255} // deep-yellow

233
glide.lock generated
View File

@ -1,233 +0,0 @@
hash: 18200e5c7afdb7086a85d33bc917911a8ea74019d5f4d2aad9cebf0d71a4c23c
updated: 2017-06-23T09:01:56.103326562-07:00
imports:
- name: bitbucket.org/zombiezen/gopdf
version: 1c63dc69751bc45441c2ce1f56b631c55294b4d5
subpackages:
- pdf
- name: cloud.google.com/go
version: 30b36efdf5c81a1d3f9fac38e1496c29e8adc420
subpackages:
- compute/metadata
- internal
- internal/optional
- storage
- name: github.com/ajstarks/svgo
version: fec71ff44529c89ddb4211a62f3d672f31e50bc5
- name: github.com/cheggaaa/pb
version: d7e6ca3010b6f084d8056847f55d7f572f180678
- name: github.com/coreos/etcd
version: 47a8156851b5a59665421661edb7c813f8a7993e
subpackages:
- auth/authpb
- client
- clientv3
- etcdserver/api/v3rpc/rpctypes
- etcdserver/etcdserverpb
- mvcc/mvccpb
- pkg/cpuutil
- pkg/netutil
- pkg/pathutil
- pkg/report
- pkg/report
- pkg/srv
- pkg/tlsutil
- pkg/types
- version
- name: github.com/coreos/go-semver
version: 8ab6407b697782a06568d4b7f1db25550ec2e4c6
subpackages:
- semver
- name: github.com/coreos/go-systemd
version: 48702e0da86bd25e76cfef347e2adeb434a0d0a6
subpackages:
- daemon
- journal
- util
- name: github.com/coreos/pkg
version: fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
subpackages:
- capnslog
- name: github.com/dustin/go-humanize
version: ef638b6c2e62b857442c6443dace9366a48c0ee2
- name: github.com/gogo/protobuf
version: 100ba4e885062801d56799d78530b73b178a78f3
subpackages:
- gogoproto
- proto
- protoc-gen-gogo/descriptor
- name: github.com/golang/freetype
version: e2365dfdc4a05e4b8299a783240d4a7d5a65d4e4
subpackages:
- raster
- truetype
- name: github.com/golang/protobuf
version: 4bd1920723d7b7c925de087aa32e2187708897f7
subpackages:
- jsonpb
- proto
- ptypes/any
- name: github.com/gonum/floats
version: a2cbc5c70616cd18491ef2843231f6ce28b2cb02
- name: github.com/gonum/internal
version: 4c20688f849035792bcee8a94ec93b5c277c919f
subpackages:
- asm/f64
- name: github.com/gonum/plot
version: 51b62dc5319d7fce41240d13e780a93e640b9a38
subpackages:
- palette
- plotter
- plotutil
- tools/bezier
- vg
- vg/draw
- vg/fonts
- vg/vgeps
- vg/vgimg
- vg/vgpdf
- vg/vgsvg
- name: github.com/googleapis/gax-go
version: 84ed26760e7f6f80887a2fbfb50db3cc415d2cea
- name: github.com/gyuho/dataframe
version: 73de2c550b1177c1640f3dacbbc1af00f913fedb
- name: github.com/gyuho/linux-inspect
version: db8def6abe6a96a20aae6ae01664cc3817a27ba0
subpackages:
- df
- etc
- inspect
- pkg/fileutil
- pkg/timeutil
- proc
- schema
- top
- name: github.com/hashicorp/consul
version: 42f60b04bba2e4391e9a95a218c873986ebeea6b
subpackages:
- api
- name: github.com/hashicorp/go-cleanhttp
version: 3573b8b52aa7b37b9358d966a898feb387f62437
- name: github.com/hashicorp/go-rootcerts
version: 6bb64b370b90e7ef1fa532be9e591a81c3493e00
- name: github.com/hashicorp/serf
version: 91fd53b1d3e624389ed9a295a3fa380e5c7b9dfc
subpackages:
- coordinate
- name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/kr/pty
version: 2c10821df3c3cf905230d078702dfbe9404c9b23
- name: github.com/llgcode/draw2d
version: dcbfbe505d35de8166ccfc47ff9e4bb020473e18
subpackages:
- draw2dbase
- draw2dimg
- name: github.com/mattn/go-runewidth
version: 9e777a8366cce605130a531d2cd6363d07ad7317
- name: github.com/mitchellh/go-homedir
version: b8bc1bf767474819792c23f32d8286a45736f1c6
- name: github.com/olekukonko/tablewriter
version: febf2d34b54a69ce7530036c7503b1c9fbfdf0bb
- name: github.com/samuel/go-zookeeper
version: 1d7be4effb13d2d908342d349d71a284a7542693
subpackages:
- zk
- name: github.com/spf13/cobra
version: 9495bc009a56819bdb0ddbc1a373e29c140bc674
- name: github.com/spf13/pflag
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
- name: github.com/ugorji/go
version: ded73eae5db7e7a0ef6f55aace87a2873c5d2b74
subpackages:
- codec
- name: golang.org/x/image
version: 426cfd8eeb6e08ab1932954e09e3c2cb2bc6e36d
subpackages:
- draw
- font
- math/f64
- math/fixed
- tiff
- tiff/lzw
- name: golang.org/x/net
version: c8c74377599bd978aee1cf3b9b63a8634051cec2
subpackages:
- context
- context/ctxhttp
- http2
- http2/hpack
- idna
- internal/timeseries
- lex/httplex
- trace
- name: golang.org/x/oauth2
version: d5040cddfc0da40b408c9a1da4728662435176a9
subpackages:
- google
- internal
- jws
- jwt
- name: golang.org/x/text
version: 19e51611da83d6be54ddafce4a4af510cb3e9ea4
subpackages:
- secure/bidirule
- transform
- unicode/bidi
- unicode/norm
- name: golang.org/x/time
version: a4bde12657593d5e90d0533a3e4fd95e635124cb
subpackages:
- rate
- name: google.golang.org/api
version: a53f28dc539c26b08a77fc5ae954e02917686ef4
subpackages:
- gensupport
- googleapi
- googleapi/internal/uritemplates
- googleapi/transport
- internal
- iterator
- option
- storage/v1
- transport
- name: google.golang.org/appengine
version: 4f7eeb5305a4ba1966344836ba4af9996b7b4e05
subpackages:
- internal
- internal/app_identity
- internal/base
- internal/datastore
- internal/log
- internal/modules
- internal/remote_api
- internal/socket
- internal/urlfetch
- socket
- urlfetch
- name: google.golang.org/genproto
version: aa2eb687b4d3e17154372564ad8d6bf11c3cf21f
subpackages:
- googleapis/rpc/status
- name: google.golang.org/grpc
version: b15215fb911b24a5d61d57feec4233d610530464
subpackages:
- codes
- credentials
- credentials/oauth
- grpclb/grpc_lb_v1
- grpclog
- health
- health/grpc_health_v1
- internal
- keepalive
- metadata
- naming
- peer
- stats
- status
- tap
- transport
- name: gopkg.in/yaml.v2
version: 53feefa2559fb8dfa8d81baad31be332c97d6c77
testImports: []

View File

@ -1,116 +0,0 @@
package: github.com/coreos/dbtester
import:
- package: cloud.google.com/go
version: 30b36efdf5c81a1d3f9fac38e1496c29e8adc420
subpackages:
- compute/metadata
- internal
- storage
- package: github.com/cheggaaa/pb
version: d7e6ca3010b6f084d8056847f55d7f572f180678
- package: github.com/coreos/etcd
version: 47a8156851b5a59665421661edb7c813f8a7993e
subpackages:
- auth/authpb
- client
- clientv3
- etcdserver/api/v3rpc/rpctypes
- etcdserver/etcdserverpb
- mvcc/mvccpb
- pkg/pathutil
- pkg/report
- pkg/tlsutil
- pkg/netutil
- pkg/types
- pkg/report
- package: github.com/coreos/pkg
version: fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
subpackages:
- capnslog
- package: github.com/dustin/go-humanize
version: ef638b6c2e62b857442c6443dace9366a48c0ee2
- package: github.com/gogo/protobuf
version: v0.4
subpackages:
- gogoproto
- proto
- protoc-gen-gogo/descriptor
- package: github.com/golang/protobuf
version: 4bd1920723d7b7c925de087aa32e2187708897f7
subpackages:
- jsonpb
- proto
- package: github.com/gonum/plot
version: 51b62dc5319d7fce41240d13e780a93e640b9a38
subpackages:
- plotter
- plotutil
- vg
- package: github.com/gyuho/dataframe
version: 73de2c550b1177c1640f3dacbbc1af00f913fedb
- package: github.com/gyuho/linux-inspect
version: db8def6abe6a96a20aae6ae01664cc3817a27ba0
subpackages:
- df
- etc
- inspect
- pkg/fileutil
- pkg/timeutil
- proc
- schema
- top
- package: github.com/hashicorp/consul
version: 42f60b04bba2e4391e9a95a218c873986ebeea6b
subpackages:
- api
- package: github.com/samuel/go-zookeeper
version: 1d7be4effb13d2d908342d349d71a284a7542693
subpackages:
- zk
- package: github.com/spf13/cobra
version: 9495bc009a56819bdb0ddbc1a373e29c140bc674
- package: golang.org/x/net
version: c8c74377599bd978aee1cf3b9b63a8634051cec2
subpackages:
- context
- context/ctxhttp
- http2
- http2/hpack
- internal/timeseries
- lex/httplex
- trace
- package: golang.org/x/oauth2
version: d5040cddfc0da40b408c9a1da4728662435176a9
subpackages:
- google
- internal
- jws
- jwt
- package: google.golang.org/api
version: a53f28dc539c26b08a77fc5ae954e02917686ef4
subpackages:
- option
- package: google.golang.org/grpc
version: v1.4.2
subpackages:
- codes
- credentials
- credentials/oauth
- grpclog
- internal
- metadata
- naming
- peer
- transport
- health
- health/grpc_health_v1
- package: gopkg.in/yaml.v2
version: 53feefa2559fb8dfa8d81baad31be332c97d6c77
- package: github.com/spf13/pflag
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
- package: golang.org/x/time
version: a4bde12657593d5e90d0533a3e4fd95e635124cb
subpackages:
- rate
- package: github.com/olekukonko/tablewriter
version: febf2d34b54a69ce7530036c7503b1c9fbfdf0bb

View File

@ -7,8 +7,8 @@ if ! [[ "$0" =~ "scripts/genproto.sh" ]]; then
fi fi
# for now, be conservative about what version of protoc we expect # for now, be conservative about what version of protoc we expect
if ! [[ $(protoc --version) =~ "3.3.0" ]]; then if ! [[ $(protoc --version) =~ "3.5.1" ]]; then
echo "could not find protoc 3.3.0, is it installed + in PATH?" echo "could not find protoc 3.5.1, is it installed + in PATH?"
exit 255 exit 255
fi fi

View File

@ -1,50 +0,0 @@
#!/usr/bin/env bash
set -e
if ! [[ "$0" =~ "scripts/update-vendor-glide.sh" ]]; then
echo "must be run from repository root"
exit 255
fi
# update depedency
# 1. edit glide.yaml with version, git SHA
# 2. run ./script-update-vendor-glide.sh
# 3. it automatically detects new git SHA, and vendors updates to cmd/vendor directory
#
# add depedency
# 1. run ./script-update-vendor-glide.sh github.com/USER/PROJECT#^1.0.0
# OR
# ./script-update-vendor-glide.sh github.com/USER/PROJECT#9b772b54b3bf0be1eec083c9669766a56332559a
# ./script-update-vendor-glide.sh golang.org/x/time#711ca1cb87636abec28122ef3bc6a77269d433f3
# 2. make sure glide.yaml and glide.lock are updated
GLIDE_ROOT="$GOPATH/src/github.com/Masterminds/glide"
GLIDE_SHA=21ff6d397ccca910873d8eaabab6a941c364cc70
go get -d -u github.com/Masterminds/glide
pushd "${GLIDE_ROOT}"
# git reset --hard HEAD
git reset --hard ${GLIDE_SHA}
go install
popd
GLIDE_VC_ROOT="$GOPATH/src/github.com/sgotti/glide-vc"
GLIDE_VC_SHA=d96375d23c85287e80296cdf48f9d21c227fa40a
go get -d -u github.com/sgotti/glide-vc
pushd "${GLIDE_VC_ROOT}"
# git reset --hard HEAD
git reset --hard ${GLIDE_VC_SHA}
go install
popd
rm -rf ./vendor
if [ -n "$1" ]; then
echo "glide get on $(echo $1)"
glide get --strip-vendor $1
else
echo "glide update on *"
glide update --strip-vendor
fi;
glide vc --no-tests --only-code

11
scripts/updatedep.sh Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -e
if ! [[ "$0" =~ "./scripts/updatedep.sh" ]]; then
echo "must be run from repository root"
exit 255
fi
go get -v -u github.com/golang/dep/cmd/dep
dep ensure -v
dep prune

View File

@ -174,13 +174,11 @@ func (cfg *Config) Stress(databaseID string) error {
plog.Println("checking total keys on", gcfg.DatabaseEndpoints) plog.Println("checking total keys on", gcfg.DatabaseEndpoints)
var totalKeysFunc func([]string) map[string]int64 var totalKeysFunc func([]string) map[string]int64
switch gcfg.DatabaseID { switch gcfg.DatabaseID {
case "etcd__v2_3": case "etcd__tip", "etcd__v3_2", "etcd__v3_3":
totalKeysFunc = getTotalKeysEtcdv2
case "etcd__v3_1", "etcd__v3_2", "etcd__tip":
totalKeysFunc = getTotalKeysEtcdv3 totalKeysFunc = getTotalKeysEtcdv3
case "zookeeper__r3_4_9", "zookeeper__r3_5_2_alpha", "zookeeper__r3_5_3_beta", "zetcd__beta": case "zookeeper__r3_5_3_beta", "zetcd__beta":
totalKeysFunc = getTotalKeysZk totalKeysFunc = getTotalKeysZk
case "consul__v0_7_5", "consul__v0_8_0", "consul__v0_8_4", "cetcd__beta": case "consul__v1_0_2", "cetcd__beta":
totalKeysFunc = getTotalKeysConsul totalKeysFunc = getTotalKeysConsul
default: default:
plog.Panicf("%q is unknown database ID", gcfg.DatabaseID) plog.Panicf("%q is unknown database ID", gcfg.DatabaseID)
@ -194,24 +192,7 @@ func (cfg *Config) Stress(databaseID string) error {
key, value := sameKey(gcfg.ConfigClientMachineBenchmarkOptions.KeySizeBytes), vals.strings[0] key, value := sameKey(gcfg.ConfigClientMachineBenchmarkOptions.KeySizeBytes), vals.strings[0]
switch gcfg.DatabaseID { switch gcfg.DatabaseID {
case "etcd__v2_3": case "etcd__tip", "etcd__v3_2", "etcd__v3_3":
plog.Infof("write started [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID)
var err error
for i := 0; i < 7; i++ {
clients := mustCreateClientsEtcdv2(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber)
_, err = clients[0].Set(context.Background(), key, value, nil)
if err != nil {
continue
}
plog.Infof("write done [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID)
break
}
if err != nil {
plog.Errorf("write error [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID)
os.Exit(1)
}
case "etcd__v3_1", "etcd__v3_2", "etcd__tip":
plog.Infof("write started [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID) plog.Infof("write started [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID)
var err error var err error
for i := 0; i < 7; i++ { for i := 0; i < 7; i++ {
@ -231,7 +212,7 @@ func (cfg *Config) Stress(databaseID string) error {
os.Exit(1) os.Exit(1)
} }
case "zookeeper__r3_4_9", "zookeeper__r3_5_2_alpha", "zookeeper__r3_5_3_beta", "zetcd__beta": case "zookeeper__r3_5_3_beta", "zetcd__beta":
plog.Infof("write started [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID) plog.Infof("write started [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID)
var err error var err error
for i := 0; i < 7; i++ { for i := 0; i < 7; i++ {
@ -251,7 +232,7 @@ func (cfg *Config) Stress(databaseID string) error {
os.Exit(1) os.Exit(1)
} }
case "consul__v0_7_5", "consul__v0_8_0", "consul__v0_8_4", "cetcd__beta": case "consul__v1_0_2", "cetcd__beta":
plog.Infof("write started [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID) plog.Infof("write started [request: PUT | key: %q | database: %q]", key, gcfg.DatabaseID)
var err error var err error
for i := 0; i < 7; i++ { for i := 0; i < 7; i++ {
@ -282,11 +263,7 @@ func (cfg *Config) Stress(databaseID string) error {
plog.Infof("writing key for read-oneshot [key: %q | database: %q]", key, gcfg.DatabaseID) plog.Infof("writing key for read-oneshot [key: %q | database: %q]", key, gcfg.DatabaseID)
var err error var err error
switch gcfg.DatabaseID { switch gcfg.DatabaseID {
case "etcd__v2_3": case "etcd__tip", "etcd__v3_2", "etcd__v3_3":
clients := mustCreateClientsEtcdv2(gcfg.DatabaseEndpoints, 1)
_, err = clients[0].Set(context.Background(), key, value, nil)
case "etcd__v3_1", "etcd__v3_2", "etcd__tip":
clients := mustCreateClientsEtcdv3(gcfg.DatabaseEndpoints, etcdv3ClientCfg{ clients := mustCreateClientsEtcdv3(gcfg.DatabaseEndpoints, etcdv3ClientCfg{
totalConns: 1, totalConns: 1,
totalClients: 1, totalClients: 1,
@ -294,12 +271,12 @@ func (cfg *Config) Stress(databaseID string) error {
_, err = clients[0].Do(context.Background(), clientv3.OpPut(key, value)) _, err = clients[0].Do(context.Background(), clientv3.OpPut(key, value))
clients[0].Close() clients[0].Close()
case "zookeeper__r3_4_9", "zookeeper__r3_5_2_alpha", "zookeeper__r3_5_3_beta", "zetcd__beta": case "zookeeper__r3_5_3_beta", "zetcd__beta":
conns := mustCreateConnsZk(gcfg.DatabaseEndpoints, 1) conns := mustCreateConnsZk(gcfg.DatabaseEndpoints, 1)
_, err = conns[0].Create("/"+key, vals.bytes[0], zkCreateFlags, zkCreateACL) _, err = conns[0].Create("/"+key, vals.bytes[0], zkCreateFlags, zkCreateACL)
conns[0].Close() conns[0].Close()
case "consul__v0_7_5", "consul__v0_8_0", "consul__v0_8_4", "cetcd__beta": case "consul__v1_0_2", "cetcd__beta":
clients := mustCreateConnsConsul(gcfg.DatabaseEndpoints, 1) clients := mustCreateConnsConsul(gcfg.DatabaseEndpoints, 1)
_, err = clients[0].Put(&consulapi.KVPair{Key: key, Value: vals.bytes[0]}, nil) _, err = clients[0].Put(&consulapi.KVPair{Key: key, Value: vals.bytes[0]}, nil)
@ -323,12 +300,7 @@ func (cfg *Config) Stress(databaseID string) error {
func newReadHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []ReqHandler, done func()) { func newReadHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []ReqHandler, done func()) {
rhs = make([]ReqHandler, gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber) rhs = make([]ReqHandler, gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber)
switch gcfg.DatabaseID { switch gcfg.DatabaseID {
case "etcd__v2_3": case "etcd__tip", "etcd__v3_2", "etcd__v3_3":
conns := mustCreateClientsEtcdv2(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber)
for i := range conns {
rhs[i] = newGetEtcd2(conns[i])
}
case "etcd__v3_1", "etcd__v3_2", "etcd__tip":
clients := mustCreateClientsEtcdv3(gcfg.DatabaseEndpoints, etcdv3ClientCfg{ clients := mustCreateClientsEtcdv3(gcfg.DatabaseEndpoints, etcdv3ClientCfg{
totalConns: gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber, totalConns: gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber,
totalClients: gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber, totalClients: gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber,
@ -341,7 +313,7 @@ func newReadHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []Req
clients[i].Close() clients[i].Close()
} }
} }
case "zookeeper__r3_4_9", "zookeeper__r3_5_2_alpha", "zookeeper__r3_5_3_beta", "zetcd__beta": case "zookeeper__r3_5_3_beta", "zetcd__beta":
conns := mustCreateConnsZk(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber) conns := mustCreateConnsZk(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber)
for i := range conns { for i := range conns {
rhs[i] = newGetZK(conns[i]) rhs[i] = newGetZK(conns[i])
@ -351,7 +323,7 @@ func newReadHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []Req
conns[i].Close() conns[i].Close()
} }
} }
case "consul__v0_7_5", "consul__v0_8_0", "consul__v0_8_4", "cetcd__beta": case "consul__v1_0_2", "cetcd__beta":
conns := mustCreateConnsConsul(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber) conns := mustCreateConnsConsul(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber)
for i := range conns { for i := range conns {
rhs[i] = newGetConsul(conns[i]) rhs[i] = newGetConsul(conns[i])
@ -365,12 +337,7 @@ func newReadHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []Req
func newWriteHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []ReqHandler, done func()) { func newWriteHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []ReqHandler, done func()) {
rhs = make([]ReqHandler, gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber) rhs = make([]ReqHandler, gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber)
switch gcfg.DatabaseID { switch gcfg.DatabaseID {
case "etcd__v2_3": case "etcd__tip", "etcd__v3_2", "etcd__v3_3":
conns := mustCreateClientsEtcdv2(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber)
for i := range conns {
rhs[i] = newPutEtcd2(conns[i])
}
case "etcd__v3_1", "etcd__v3_2", "etcd__tip":
etcdClients := mustCreateClientsEtcdv3(gcfg.DatabaseEndpoints, etcdv3ClientCfg{ etcdClients := mustCreateClientsEtcdv3(gcfg.DatabaseEndpoints, etcdv3ClientCfg{
totalConns: gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber, totalConns: gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber,
totalClients: gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber, totalClients: gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber,
@ -383,7 +350,7 @@ func newWriteHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []Re
etcdClients[i].Close() etcdClients[i].Close()
} }
} }
case "zookeeper__r3_4_9", "zookeeper__r3_5_2_alpha", "zookeeper__r3_5_3_beta", "zetcd__beta": case "zookeeper__r3_5_3_beta", "zetcd__beta":
if gcfg.ConfigClientMachineBenchmarkOptions.SameKey { if gcfg.ConfigClientMachineBenchmarkOptions.SameKey {
key := sameKey(gcfg.ConfigClientMachineBenchmarkOptions.KeySizeBytes) key := sameKey(gcfg.ConfigClientMachineBenchmarkOptions.KeySizeBytes)
valueBts := randBytes(gcfg.ConfigClientMachineBenchmarkOptions.ValueSizeBytes) valueBts := randBytes(gcfg.ConfigClientMachineBenchmarkOptions.ValueSizeBytes)
@ -420,7 +387,7 @@ func newWriteHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []Re
conns[i].Close() conns[i].Close()
} }
} }
case "consul__v0_7_5", "consul__v0_8_0", "consul__v0_8_4", "cetcd__beta": case "consul__v1_0_2", "cetcd__beta":
conns := mustCreateConnsConsul(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber) conns := mustCreateConnsConsul(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber)
for i := range conns { for i := range conns {
rhs[i] = newPutConsul(conns[i]) rhs[i] = newPutConsul(conns[i])
@ -440,14 +407,7 @@ func newWriteHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (rhs []Re
func newReadOneshotHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) []ReqHandler { func newReadOneshotHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) []ReqHandler {
rhs := make([]ReqHandler, gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber) rhs := make([]ReqHandler, gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber)
switch gcfg.DatabaseID { switch gcfg.DatabaseID {
case "etcd__v2_3": case "etcd__tip", "etcd__v3_2", "etcd__v3_3":
for i := range rhs {
rhs[i] = func(ctx context.Context, req *request) error {
conns := mustCreateClientsEtcdv2(gcfg.DatabaseEndpoints, 1)
return newGetEtcd2(conns[0])(ctx, req)
}
}
case "etcd__v3_1", "etcd__v3_2", "etcd__tip":
for i := range rhs { for i := range rhs {
rhs[i] = func(ctx context.Context, req *request) error { rhs[i] = func(ctx context.Context, req *request) error {
conns := mustCreateClientsEtcdv3(gcfg.DatabaseEndpoints, etcdv3ClientCfg{ conns := mustCreateClientsEtcdv3(gcfg.DatabaseEndpoints, etcdv3ClientCfg{
@ -458,7 +418,7 @@ func newReadOneshotHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) []R
return newGetEtcd3(conns[0])(ctx, req) return newGetEtcd3(conns[0])(ctx, req)
} }
} }
case "zookeeper__r3_4_9", "zookeeper__r3_5_2_alpha", "zookeeper__r3_5_3_beta", "zetcd__beta": case "zookeeper__r3_5_3_beta", "zetcd__beta":
for i := range rhs { for i := range rhs {
rhs[i] = func(ctx context.Context, req *request) error { rhs[i] = func(ctx context.Context, req *request) error {
conns := mustCreateConnsZk(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber) conns := mustCreateConnsZk(gcfg.DatabaseEndpoints, gcfg.ConfigClientMachineBenchmarkOptions.ConnectionNumber)
@ -466,7 +426,7 @@ func newReadOneshotHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) []R
return newGetZK(conns[0])(ctx, req) return newGetZK(conns[0])(ctx, req)
} }
} }
case "consul__v0_7_5", "consul__v0_8_0", "consul__v0_8_4", "cetcd__beta": case "consul__v1_0_2", "cetcd__beta":
for i := range rhs { for i := range rhs {
rhs[i] = func(ctx context.Context, req *request) error { rhs[i] = func(ctx context.Context, req *request) error {
conns := mustCreateConnsConsul(gcfg.DatabaseEndpoints, 1) conns := mustCreateConnsConsul(gcfg.DatabaseEndpoints, 1)
@ -496,25 +456,21 @@ func generateReads(gcfg dbtesterpb.ConfigClientMachineAgentControl, key string,
} }
switch gcfg.DatabaseID { switch gcfg.DatabaseID {
case "etcd__v2_3": case "etcd__tip", "etcd__v3_2", "etcd__v3_3":
// serializable read by default
inflightReqs <- request{etcdv2Op: etcdv2Op{key: key}}
case "etcd__v3_1", "etcd__v3_2", "etcd__tip":
opts := []clientv3.OpOption{clientv3.WithRange("")} opts := []clientv3.OpOption{clientv3.WithRange("")}
if gcfg.ConfigClientMachineBenchmarkOptions.StaleRead { if gcfg.ConfigClientMachineBenchmarkOptions.StaleRead {
opts = append(opts, clientv3.WithSerializable()) opts = append(opts, clientv3.WithSerializable())
} }
inflightReqs <- request{etcdv3Op: clientv3.OpGet(key, opts...)} inflightReqs <- request{etcdv3Op: clientv3.OpGet(key, opts...)}
case "zookeeper__r3_4_9", "zookeeper__r3_5_2_alpha", "zookeeper__r3_5_3_beta", "zetcd__beta": case "zookeeper__r3_5_3_beta", "zetcd__beta":
op := zkOp{key: key} op := zkOp{key: key}
if gcfg.ConfigClientMachineBenchmarkOptions.StaleRead { if gcfg.ConfigClientMachineBenchmarkOptions.StaleRead {
op.staleRead = true op.staleRead = true
} }
inflightReqs <- request{zkOp: op} inflightReqs <- request{zkOp: op}
case "consul__v0_7_5", "consul__v0_8_0", "consul__v0_8_4", "cetcd__beta": case "consul__v1_0_2", "cetcd__beta":
op := consulOp{key: key} op := consulOp{key: key}
if gcfg.ConfigClientMachineBenchmarkOptions.StaleRead { if gcfg.ConfigClientMachineBenchmarkOptions.StaleRead {
op.staleRead = true op.staleRead = true
@ -555,13 +511,11 @@ func generateWrites(gcfg dbtesterpb.ConfigClientMachineAgentControl, startIdx in
} }
switch gcfg.DatabaseID { switch gcfg.DatabaseID {
case "etcd__v2_3": case "etcd__tip", "etcd__v3_2", "etcd__v3_3":
inflightReqs <- request{etcdv2Op: etcdv2Op{key: k, value: vs}}
case "etcd__v3_1", "etcd__v3_2", "etcd__tip":
inflightReqs <- request{etcdv3Op: clientv3.OpPut(k, vs)} inflightReqs <- request{etcdv3Op: clientv3.OpPut(k, vs)}
case "zookeeper__r3_4_9", "zookeeper__r3_5_2_alpha", "zookeeper__r3_5_3_beta", "zetcd__beta": case "zookeeper__r3_5_3_beta", "zetcd__beta":
inflightReqs <- request{zkOp: zkOp{key: "/" + k, value: v}} inflightReqs <- request{zkOp: zkOp{key: "/" + k, value: v}}
case "consul__v0_7_5", "consul__v0_8_0", "consul__v0_8_4", "cetcd__beta": case "consul__v1_0_2", "cetcd__beta":
inflightReqs <- request{consulOp: consulOp{key: k, value: v}} inflightReqs <- request{consulOp: consulOp{key: k, value: v}}
default: default:
plog.Panicf("%q is unknown database ID", gcfg.DatabaseID) plog.Panicf("%q is unknown database ID", gcfg.DatabaseID)

View File

@ -20,7 +20,6 @@ import (
) )
type request struct { type request struct {
etcdv2Op etcdv2Op
etcdv3Op clientv3.Op etcdv3Op clientv3.Op
zkOp zkOp zkOp zkOp
consulOp consulOp consulOp consulOp

View File

@ -1,87 +0,0 @@
// Copyright 2017 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 dbtester
import (
"net"
"net/http"
"strings"
"time"
clientv2 "github.com/coreos/etcd/client"
"golang.org/x/net/context"
)
func mustCreateClientsEtcdv2(endpoints []string, total int64) []clientv2.KeysAPI {
cks := make([]clientv2.KeysAPI, total)
for i := range cks {
endpoint := endpoints[dialTotal%len(endpoints)]
dialTotal++
if !strings.HasPrefix(endpoint, "http://") {
endpoint = "http://" + endpoint
}
tr := &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
}
cfg := clientv2.Config{
Endpoints: []string{endpoint},
Transport: tr,
HeaderTimeoutPerRequest: time.Second,
}
c, err := clientv2.New(cfg)
if err != nil {
plog.Fatal(err)
}
kapi := clientv2.NewKeysAPI(c)
cks[i] = kapi
}
return cks
}
type etcdv2Op struct {
key string
value string
}
func newPutEtcd2(conn clientv2.KeysAPI) ReqHandler {
return func(ctx context.Context, req *request) error {
op := req.etcdv2Op
_, err := conn.Set(context.Background(), op.key, op.value, nil)
return err
}
}
func newGetEtcd2(conn clientv2.KeysAPI) ReqHandler {
return func(ctx context.Context, req *request) error {
_, err := conn.Get(ctx, req.etcdv2Op.key, nil)
return err
}
}
func getTotalKeysEtcdv2(endpoints []string) map[string]int64 {
rs := make(map[string]int64)
for _, ep := range endpoints {
rs[ep] = 0 // not supported in metrics
}
return rs
}

2
vendor/cloud.google.com/go/LICENSE generated vendored
View File

@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
Copyright 2014 Google Inc. Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

20
vendor/cloud.google.com/go/cloud.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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 cloud is the root of the packages used to access Google Cloud
// Services. See https://godoc.org/cloud.google.com/go for a full list
// of sub-packages.
//
// This package documents how to authorize and authenticate the sub packages.
package cloud // import "cloud.google.com/go"

View File

@ -34,8 +34,6 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp" "golang.org/x/net/context/ctxhttp"
"cloud.google.com/go/internal"
) )
const ( const (
@ -48,6 +46,8 @@ const (
// This is variable name is not defined by any spec, as far as // This is variable name is not defined by any spec, as far as
// I know; it was made up for the Go package. // I know; it was made up for the Go package.
metadataHostEnv = "GCE_METADATA_HOST" metadataHostEnv = "GCE_METADATA_HOST"
userAgent = "gcloud-golang/0.1"
) )
type cachedValue struct { type cachedValue struct {
@ -65,24 +65,20 @@ var (
var ( var (
metaClient = &http.Client{ metaClient = &http.Client{
Transport: &internal.Transport{ Transport: &http.Transport{
Base: &http.Transport{ Dial: (&net.Dialer{
Dial: (&net.Dialer{ Timeout: 2 * time.Second,
Timeout: 2 * time.Second, KeepAlive: 30 * time.Second,
KeepAlive: 30 * time.Second, }).Dial,
}).Dial, ResponseHeaderTimeout: 2 * time.Second,
ResponseHeaderTimeout: 2 * time.Second,
},
}, },
} }
subscribeClient = &http.Client{ subscribeClient = &http.Client{
Transport: &internal.Transport{ Transport: &http.Transport{
Base: &http.Transport{ Dial: (&net.Dialer{
Dial: (&net.Dialer{ Timeout: 2 * time.Second,
Timeout: 2 * time.Second, KeepAlive: 30 * time.Second,
KeepAlive: 30 * time.Second, }).Dial,
}).Dial,
},
}, },
} }
) )
@ -132,6 +128,7 @@ func getETag(client *http.Client, suffix string) (value, etag string, err error)
url := "http://" + host + "/computeMetadata/v1/" + suffix url := "http://" + host + "/computeMetadata/v1/" + suffix
req, _ := http.NewRequest("GET", url, nil) req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Metadata-Flavor", "Google") req.Header.Set("Metadata-Flavor", "Google")
req.Header.Set("User-Agent", userAgent)
res, err := client.Do(req) res, err := client.Do(req)
if err != nil { if err != nil {
return "", "", err return "", "", err
@ -202,7 +199,9 @@ func testOnGCE() bool {
// Try two strategies in parallel. // Try two strategies in parallel.
// See https://github.com/GoogleCloudPlatform/google-cloud-go/issues/194 // See https://github.com/GoogleCloudPlatform/google-cloud-go/issues/194
go func() { go func() {
res, err := ctxhttp.Get(ctx, metaClient, "http://"+metadataIP) req, _ := http.NewRequest("GET", "http://"+metadataIP, nil)
req.Header.Set("User-Agent", userAgent)
res, err := ctxhttp.Do(ctx, metaClient, req)
if err != nil { if err != nil {
resc <- false resc <- false
return return

256
vendor/cloud.google.com/go/iam/iam.go generated vendored Normal file
View File

@ -0,0 +1,256 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 iam supports the resource-specific operations of Google Cloud
// IAM (Identity and Access Management) for the Google Cloud Libraries.
// See https://cloud.google.com/iam for more about IAM.
//
// Users of the Google Cloud Libraries will typically not use this package
// directly. Instead they will begin with some resource that supports IAM, like
// a pubsub topic, and call its IAM method to get a Handle for that resource.
package iam
import (
"golang.org/x/net/context"
pb "google.golang.org/genproto/googleapis/iam/v1"
"google.golang.org/grpc"
)
// client abstracts the IAMPolicy API to allow multiple implementations.
type client interface {
Get(ctx context.Context, resource string) (*pb.Policy, error)
Set(ctx context.Context, resource string, p *pb.Policy) error
Test(ctx context.Context, resource string, perms []string) ([]string, error)
}
// grpcClient implements client for the standard gRPC-based IAMPolicy service.
type grpcClient struct {
c pb.IAMPolicyClient
}
func (g *grpcClient) Get(ctx context.Context, resource string) (*pb.Policy, error) {
proto, err := g.c.GetIamPolicy(ctx, &pb.GetIamPolicyRequest{Resource: resource})
if err != nil {
return nil, err
}
return proto, nil
}
func (g *grpcClient) Set(ctx context.Context, resource string, p *pb.Policy) error {
_, err := g.c.SetIamPolicy(ctx, &pb.SetIamPolicyRequest{
Resource: resource,
Policy: p,
})
return err
}
func (g *grpcClient) Test(ctx context.Context, resource string, perms []string) ([]string, error) {
res, err := g.c.TestIamPermissions(ctx, &pb.TestIamPermissionsRequest{
Resource: resource,
Permissions: perms,
})
if err != nil {
return nil, err
}
return res.Permissions, nil
}
// A Handle provides IAM operations for a resource.
type Handle struct {
c client
resource string
}
// InternalNewHandle is for use by the Google Cloud Libraries only.
//
// InternalNewHandle returns a Handle for resource.
// The conn parameter refers to a server that must support the IAMPolicy service.
func InternalNewHandle(conn *grpc.ClientConn, resource string) *Handle {
return InternalNewHandleClient(&grpcClient{c: pb.NewIAMPolicyClient(conn)}, resource)
}
// InternalNewHandleClient is for use by the Google Cloud Libraries only.
//
// InternalNewHandleClient returns a Handle for resource using the given
// client implementation.
func InternalNewHandleClient(c client, resource string) *Handle {
return &Handle{
c: c,
resource: resource,
}
}
// Policy retrieves the IAM policy for the resource.
func (h *Handle) Policy(ctx context.Context) (*Policy, error) {
proto, err := h.c.Get(ctx, h.resource)
if err != nil {
return nil, err
}
return &Policy{InternalProto: proto}, nil
}
// SetPolicy replaces the resource's current policy with the supplied Policy.
//
// If policy was created from a prior call to Get, then the modification will
// only succeed if the policy has not changed since the Get.
func (h *Handle) SetPolicy(ctx context.Context, policy *Policy) error {
return h.c.Set(ctx, h.resource, policy.InternalProto)
}
// TestPermissions returns the subset of permissions that the caller has on the resource.
func (h *Handle) TestPermissions(ctx context.Context, permissions []string) ([]string, error) {
return h.c.Test(ctx, h.resource, permissions)
}
// A RoleName is a name representing a collection of permissions.
type RoleName string
// Common role names.
const (
Owner RoleName = "roles/owner"
Editor RoleName = "roles/editor"
Viewer RoleName = "roles/viewer"
)
const (
// AllUsers is a special member that denotes all users, even unauthenticated ones.
AllUsers = "allUsers"
// AllAuthenticatedUsers is a special member that denotes all authenticated users.
AllAuthenticatedUsers = "allAuthenticatedUsers"
)
// A Policy is a list of Bindings representing roles
// granted to members.
//
// The zero Policy is a valid policy with no bindings.
type Policy struct {
// TODO(jba): when type aliases are available, put Policy into an internal package
// and provide an exported alias here.
// This field is exported for use by the Google Cloud Libraries only.
// It may become unexported in a future release.
InternalProto *pb.Policy
}
// Members returns the list of members with the supplied role.
// The return value should not be modified. Use Add and Remove
// to modify the members of a role.
func (p *Policy) Members(r RoleName) []string {
b := p.binding(r)
if b == nil {
return nil
}
return b.Members
}
// HasRole reports whether member has role r.
func (p *Policy) HasRole(member string, r RoleName) bool {
return memberIndex(member, p.binding(r)) >= 0
}
// Add adds member member to role r if it is not already present.
// A new binding is created if there is no binding for the role.
func (p *Policy) Add(member string, r RoleName) {
b := p.binding(r)
if b == nil {
if p.InternalProto == nil {
p.InternalProto = &pb.Policy{}
}
p.InternalProto.Bindings = append(p.InternalProto.Bindings, &pb.Binding{
Role: string(r),
Members: []string{member},
})
return
}
if memberIndex(member, b) < 0 {
b.Members = append(b.Members, member)
return
}
}
// Remove removes member from role r if it is present.
func (p *Policy) Remove(member string, r RoleName) {
bi := p.bindingIndex(r)
if bi < 0 {
return
}
bindings := p.InternalProto.Bindings
b := bindings[bi]
mi := memberIndex(member, b)
if mi < 0 {
return
}
// Order doesn't matter for bindings or members, so to remove, move the last item
// into the removed spot and shrink the slice.
if len(b.Members) == 1 {
// Remove binding.
last := len(bindings) - 1
bindings[bi] = bindings[last]
bindings[last] = nil
p.InternalProto.Bindings = bindings[:last]
return
}
// Remove member.
// TODO(jba): worry about multiple copies of m?
last := len(b.Members) - 1
b.Members[mi] = b.Members[last]
b.Members[last] = ""
b.Members = b.Members[:last]
}
// Roles returns the names of all the roles that appear in the Policy.
func (p *Policy) Roles() []RoleName {
if p.InternalProto == nil {
return nil
}
var rns []RoleName
for _, b := range p.InternalProto.Bindings {
rns = append(rns, RoleName(b.Role))
}
return rns
}
// binding returns the Binding for the suppied role, or nil if there isn't one.
func (p *Policy) binding(r RoleName) *pb.Binding {
i := p.bindingIndex(r)
if i < 0 {
return nil
}
return p.InternalProto.Bindings[i]
}
func (p *Policy) bindingIndex(r RoleName) int {
if p.InternalProto == nil {
return -1
}
for i, b := range p.InternalProto.Bindings {
if b.Role == string(r) {
return i
}
}
return -1
}
// memberIndex returns the index of m in b's Members, or -1 if not found.
func memberIndex(m string, b *pb.Binding) int {
if b == nil {
return -1
}
for i, mm := range b.Members {
if mm == m {
return i
}
}
return -1
}

54
vendor/cloud.google.com/go/internal/annotate.go generated vendored Normal file
View File

@ -0,0 +1,54 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 internal
import (
"fmt"
"google.golang.org/api/googleapi"
"google.golang.org/grpc/status"
)
// Annotate prepends msg to the error message in err, attempting
// to preserve other information in err, like an error code.
//
// Annotate panics if err is nil.
//
// Annotate knows about these error types:
// - "google.golang.org/grpc/status".Status
// - "google.golang.org/api/googleapi".Error
// If the error is not one of these types, Annotate behaves
// like
// fmt.Errorf("%s: %v", msg, err)
func Annotate(err error, msg string) error {
if err == nil {
panic("Annotate called with nil")
}
if s, ok := status.FromError(err); ok {
p := s.Proto()
p.Message = msg + ": " + p.Message
return status.ErrorProto(p)
}
if g, ok := err.(*googleapi.Error); ok {
g.Message = msg + ": " + g.Message
return g
}
return fmt.Errorf("%s: %v", msg, err)
}
// Annotatef uses format and args to format a string, then calls Annotate.
func Annotatef(err error, format string, args ...interface{}) error {
return Annotate(err, fmt.Sprintf(format, args...))
}

View File

@ -1,64 +0,0 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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 internal provides support for the cloud packages.
//
// Users should not import this package directly.
package internal
import (
"fmt"
"net/http"
)
const userAgent = "gcloud-golang/0.1"
// Transport is an http.RoundTripper that appends Google Cloud client's
// user-agent to the original request's user-agent header.
type Transport struct {
// TODO(bradfitz): delete internal.Transport. It's too wrappy for what it does.
// Do User-Agent some other way.
// Base is the actual http.RoundTripper
// requests will use. It must not be nil.
Base http.RoundTripper
}
// RoundTrip appends a user-agent to the existing user-agent
// header and delegates the request to the base http.RoundTripper.
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
req = cloneRequest(req)
ua := req.Header.Get("User-Agent")
if ua == "" {
ua = userAgent
} else {
ua = fmt.Sprintf("%s %s", ua, userAgent)
}
req.Header.Set("User-Agent", ua)
return t.Base.RoundTrip(req)
}
// cloneRequest returns a clone of the provided *http.Request.
// The clone is a shallow copy of the struct and its Header map.
func cloneRequest(r *http.Request) *http.Request {
// shallow copy of the struct
r2 := new(http.Request)
*r2 = *r
// deep copy of the Header
r2.Header = make(http.Header)
for k, s := range r.Header {
r2.Header[k] = s
}
return r2
}

View File

@ -20,6 +20,7 @@ package optional
import ( import (
"fmt" "fmt"
"strings" "strings"
"time"
) )
type ( type (
@ -37,6 +38,9 @@ type (
// Float64 is either a float64 or nil. // Float64 is either a float64 or nil.
Float64 interface{} Float64 interface{}
// Duration is either a time.Duration or nil.
Duration interface{}
) )
// ToBool returns its argument as a bool. // ToBool returns its argument as a bool.
@ -89,6 +93,16 @@ func ToFloat64(v Float64) float64 {
return x return x
} }
// ToDuration returns its argument as a time.Duration.
// It panics if its argument is nil or not a time.Duration.
func ToDuration(v Duration) time.Duration {
x, ok := v.(time.Duration)
if !ok {
doPanic("Duration", v)
}
return x
}
func doPanic(capType string, v interface{}) { func doPanic(capType string, v interface{}) {
panic(fmt.Sprintf("optional.%s value should be %s, got %T", capType, strings.ToLower(capType), v)) panic(fmt.Sprintf("optional.%s value should be %s, got %T", capType, strings.ToLower(capType), v))
} }

55
vendor/cloud.google.com/go/internal/retry.go generated vendored Normal file
View File

@ -0,0 +1,55 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 internal
import (
"time"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
)
// Retry calls the supplied function f repeatedly according to the provided
// backoff parameters. It returns when one of the following occurs:
// When f's first return value is true, Retry immediately returns with f's second
// return value.
// When the provided context is done, Retry returns with an error that
// includes both ctx.Error() and the last error returned by f.
func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error)) error {
return retry(ctx, bo, f, gax.Sleep)
}
func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error),
sleep func(context.Context, time.Duration) error) error {
var lastErr error
for {
stop, err := f()
if stop {
return err
}
// Remember the last "real" error from f.
if err != nil && err != context.Canceled && err != context.DeadlineExceeded {
lastErr = err
}
p := bo.Pause()
if cerr := sleep(ctx, p); cerr != nil {
if lastErr != nil {
return Annotatef(lastErr, "retry failed with %v; last error", cerr)
}
return cerr
}
}
}

71
vendor/cloud.google.com/go/internal/version/version.go generated vendored Normal file
View File

@ -0,0 +1,71 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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.
//go:generate ./update_version.sh
// Package version contains version information for Google Cloud Client
// Libraries for Go, as reported in request headers.
package version
import (
"runtime"
"strings"
"unicode"
)
// Repo is the current version of the client libraries in this
// repo. It should be a date in YYYYMMDD format.
const Repo = "20171211"
// Go returns the Go runtime version. The returned string
// has no whitespace.
func Go() string {
return goVersion
}
var goVersion = goVer(runtime.Version())
const develPrefix = "devel +"
func goVer(s string) string {
if strings.HasPrefix(s, develPrefix) {
s = s[len(develPrefix):]
if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
s = s[:p]
}
return s
}
if strings.HasPrefix(s, "go1") {
s = s[2:]
var prerelease string
if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
s, prerelease = s[:p], s[p:]
}
if strings.HasSuffix(s, ".") {
s += "0"
} else if strings.Count(s, ".") < 2 {
s += ".0"
}
if prerelease != "" {
s += "-" + prerelease
}
return s
}
return ""
}
func notSemverRune(r rune) bool {
return strings.IndexRune("0123456789.", r) < 0
}

View File

@ -15,9 +15,11 @@
package storage package storage
import ( import (
"fmt" "net/http"
"reflect"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/api/googleapi"
raw "google.golang.org/api/storage/v1" raw "google.golang.org/api/storage/v1"
) )
@ -27,6 +29,7 @@ type ACLRole string
const ( const (
RoleOwner ACLRole = "OWNER" RoleOwner ACLRole = "OWNER"
RoleReader ACLRole = "READER" RoleReader ACLRole = "READER"
RoleWriter ACLRole = "WRITER"
) )
// ACLEntity refers to a user or group. // ACLEntity refers to a user or group.
@ -52,10 +55,11 @@ type ACLRule struct {
// ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object. // ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object.
type ACLHandle struct { type ACLHandle struct {
c *Client c *Client
bucket string bucket string
object string object string
isDefault bool isDefault bool
userProject string // for requester-pays buckets
} }
// Delete permanently deletes the ACL entry for the given entity. // Delete permanently deletes the ACL entry for the given entity.
@ -72,10 +76,10 @@ func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) error {
// Set sets the permission level for the given entity. // Set sets the permission level for the given entity.
func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) error { func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) error {
if a.object != "" { if a.object != "" {
return a.objectSet(ctx, entity, role) return a.objectSet(ctx, entity, role, false)
} }
if a.isDefault { if a.isDefault {
return a.bucketDefaultSet(ctx, entity, role) return a.objectSet(ctx, entity, role, true)
} }
return a.bucketSet(ctx, entity, role) return a.bucketSet(ctx, entity, role)
} }
@ -95,50 +99,36 @@ func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) {
var acls *raw.ObjectAccessControls var acls *raw.ObjectAccessControls
var err error var err error
err = runWithRetry(ctx, func() error { err = runWithRetry(ctx, func() error {
acls, err = a.c.raw.DefaultObjectAccessControls.List(a.bucket).Context(ctx).Do() req := a.c.raw.DefaultObjectAccessControls.List(a.bucket)
a.configureCall(req, ctx)
acls, err = req.Do()
return err return err
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("storage: error listing default object ACL for bucket %q: %v", a.bucket, err) return nil, err
} }
return toACLRules(acls.Items), nil return toACLRules(acls.Items), nil
} }
func (a *ACLHandle) bucketDefaultSet(ctx context.Context, entity ACLEntity, role ACLRole) error {
acl := &raw.ObjectAccessControl{
Bucket: a.bucket,
Entity: string(entity),
Role: string(role),
}
err := runWithRetry(ctx, func() error {
_, err := a.c.raw.DefaultObjectAccessControls.Update(a.bucket, string(entity), acl).Context(ctx).Do()
return err
})
if err != nil {
return fmt.Errorf("storage: error updating default ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err)
}
return nil
}
func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error { func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error {
err := runWithRetry(ctx, func() error { return runWithRetry(ctx, func() error {
return a.c.raw.DefaultObjectAccessControls.Delete(a.bucket, string(entity)).Context(ctx).Do() req := a.c.raw.DefaultObjectAccessControls.Delete(a.bucket, string(entity))
a.configureCall(req, ctx)
return req.Do()
}) })
if err != nil {
return fmt.Errorf("storage: error deleting default ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err)
}
return nil
} }
func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) { func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) {
var acls *raw.BucketAccessControls var acls *raw.BucketAccessControls
var err error var err error
err = runWithRetry(ctx, func() error { err = runWithRetry(ctx, func() error {
acls, err = a.c.raw.BucketAccessControls.List(a.bucket).Context(ctx).Do() req := a.c.raw.BucketAccessControls.List(a.bucket)
a.configureCall(req, ctx)
acls, err = req.Do()
return err return err
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("storage: error listing bucket ACL for bucket %q: %v", a.bucket, err) return nil, err
} }
r := make([]ACLRule, len(acls.Items)) r := make([]ACLRule, len(acls.Items))
for i, v := range acls.Items { for i, v := range acls.Items {
@ -155,21 +145,25 @@ func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRol
Role: string(role), Role: string(role),
} }
err := runWithRetry(ctx, func() error { err := runWithRetry(ctx, func() error {
_, err := a.c.raw.BucketAccessControls.Update(a.bucket, string(entity), acl).Context(ctx).Do() req := a.c.raw.BucketAccessControls.Update(a.bucket, string(entity), acl)
a.configureCall(req, ctx)
_, err := req.Do()
return err return err
}) })
if err != nil { if err != nil {
return fmt.Errorf("storage: error updating bucket ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) return err
} }
return nil return nil
} }
func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error { func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error {
err := runWithRetry(ctx, func() error { err := runWithRetry(ctx, func() error {
return a.c.raw.BucketAccessControls.Delete(a.bucket, string(entity)).Context(ctx).Do() req := a.c.raw.BucketAccessControls.Delete(a.bucket, string(entity))
a.configureCall(req, ctx)
return req.Do()
}) })
if err != nil { if err != nil {
return fmt.Errorf("storage: error deleting bucket ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) return err
} }
return nil return nil
} }
@ -178,39 +172,58 @@ func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) {
var acls *raw.ObjectAccessControls var acls *raw.ObjectAccessControls
var err error var err error
err = runWithRetry(ctx, func() error { err = runWithRetry(ctx, func() error {
acls, err = a.c.raw.ObjectAccessControls.List(a.bucket, a.object).Context(ctx).Do() req := a.c.raw.ObjectAccessControls.List(a.bucket, a.object)
a.configureCall(req, ctx)
acls, err = req.Do()
return err return err
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("storage: error listing object ACL for bucket %q, file %q: %v", a.bucket, a.object, err) return nil, err
} }
return toACLRules(acls.Items), nil return toACLRules(acls.Items), nil
} }
func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole) error { func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole, isBucketDefault bool) error {
type setRequest interface {
Do(opts ...googleapi.CallOption) (*raw.ObjectAccessControl, error)
Header() http.Header
}
acl := &raw.ObjectAccessControl{ acl := &raw.ObjectAccessControl{
Bucket: a.bucket, Bucket: a.bucket,
Entity: string(entity), Entity: string(entity),
Role: string(role), Role: string(role),
} }
err := runWithRetry(ctx, func() error { var req setRequest
_, err := a.c.raw.ObjectAccessControls.Update(a.bucket, a.object, string(entity), acl).Context(ctx).Do() if isBucketDefault {
req = a.c.raw.DefaultObjectAccessControls.Update(a.bucket, string(entity), acl)
} else {
req = a.c.raw.ObjectAccessControls.Update(a.bucket, a.object, string(entity), acl)
}
a.configureCall(req, ctx)
return runWithRetry(ctx, func() error {
_, err := req.Do()
return err return err
}) })
if err != nil {
return fmt.Errorf("storage: error updating object ACL entry for bucket %q, file %q, entity %q: %v", a.bucket, a.object, entity, err)
}
return nil
} }
func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error { func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error {
err := runWithRetry(ctx, func() error { return runWithRetry(ctx, func() error {
return a.c.raw.ObjectAccessControls.Delete(a.bucket, a.object, string(entity)).Context(ctx).Do() req := a.c.raw.ObjectAccessControls.Delete(a.bucket, a.object, string(entity))
a.configureCall(req, ctx)
return req.Do()
}) })
if err != nil { }
return fmt.Errorf("storage: error deleting object ACL entry for bucket %q, file %q, entity %q: %v", a.bucket, a.object, entity, err)
func (a *ACLHandle) configureCall(call interface {
Header() http.Header
}, ctx context.Context) {
vc := reflect.ValueOf(call)
vc.MethodByName("Context").Call([]reflect.Value{reflect.ValueOf(ctx)})
if a.userProject != "" {
vc.MethodByName("UserProject").Call([]reflect.Value{reflect.ValueOf(a.userProject)})
} }
return nil setClientHeader(call.Header())
} }
func toACLRules(items []*raw.ObjectAccessControl) []ACLRule { func toACLRules(items []*raw.ObjectAccessControl) []ACLRule {

View File

@ -1,4 +1,4 @@
// Copyright 2014 Google Inc. All Rights Reserved. // Copyright 2014 Google Inc. LiveAndArchived Rights Reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -15,15 +15,52 @@
package storage package storage
import ( import (
"fmt"
"net/http" "net/http"
"reflect"
"time" "time"
"cloud.google.com/go/internal/optional"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/api/googleapi" "google.golang.org/api/googleapi"
"google.golang.org/api/iterator" "google.golang.org/api/iterator"
raw "google.golang.org/api/storage/v1" raw "google.golang.org/api/storage/v1"
) )
// BucketHandle provides operations on a Google Cloud Storage bucket.
// Use Client.Bucket to get a handle.
type BucketHandle struct {
c *Client
name string
acl ACLHandle
defaultObjectACL ACLHandle
conds *BucketConditions
userProject string // project for Requester Pays buckets
}
// Bucket returns a BucketHandle, which provides operations on the named bucket.
// This call does not perform any network operations.
//
// The supplied name must contain only lowercase letters, numbers, dashes,
// underscores, and dots. The full specification for valid bucket names can be
// found at:
// https://cloud.google.com/storage/docs/bucket-naming
func (c *Client) Bucket(name string) *BucketHandle {
return &BucketHandle{
c: c,
name: name,
acl: ACLHandle{
c: c,
bucket: name,
},
defaultObjectACL: ACLHandle{
c: c,
bucket: name,
isDefault: true,
},
}
}
// Create creates the Bucket in the project. // Create creates the Bucket in the project.
// If attrs is nil the API defaults will be used. // If attrs is nil the API defaults will be used.
func (b *BucketHandle) Create(ctx context.Context, projectID string, attrs *BucketAttrs) error { func (b *BucketHandle) Create(ctx context.Context, projectID string, attrs *BucketAttrs) error {
@ -34,16 +71,37 @@ func (b *BucketHandle) Create(ctx context.Context, projectID string, attrs *Buck
bkt = &raw.Bucket{} bkt = &raw.Bucket{}
} }
bkt.Name = b.name bkt.Name = b.name
// If there is lifecycle information but no location, explicitly set
// the location. This is a GCS quirk/bug.
if bkt.Location == "" && bkt.Lifecycle != nil {
bkt.Location = "US"
}
req := b.c.raw.Buckets.Insert(projectID, bkt) req := b.c.raw.Buckets.Insert(projectID, bkt)
setClientHeader(req.Header())
return runWithRetry(ctx, func() error { _, err := req.Context(ctx).Do(); return err }) return runWithRetry(ctx, func() error { _, err := req.Context(ctx).Do(); return err })
} }
// Delete deletes the Bucket. // Delete deletes the Bucket.
func (b *BucketHandle) Delete(ctx context.Context) error { func (b *BucketHandle) Delete(ctx context.Context) error {
req := b.c.raw.Buckets.Delete(b.name) req, err := b.newDeleteCall()
if err != nil {
return err
}
return runWithRetry(ctx, func() error { return req.Context(ctx).Do() }) return runWithRetry(ctx, func() error { return req.Context(ctx).Do() })
} }
func (b *BucketHandle) newDeleteCall() (*raw.BucketsDeleteCall, error) {
req := b.c.raw.Buckets.Delete(b.name)
setClientHeader(req.Header())
if err := applyBucketConds("BucketHandle.Delete", b.conds, req); err != nil {
return nil, err
}
if b.userProject != "" {
req.UserProject(b.userProject)
}
return req, nil
}
// ACL returns an ACLHandle, which provides access to the bucket's access control list. // ACL returns an ACLHandle, which provides access to the bucket's access control list.
// This controls who can list, create or overwrite the objects in a bucket. // This controls who can list, create or overwrite the objects in a bucket.
// This call does not perform any network operations. // This call does not perform any network operations.
@ -70,20 +128,25 @@ func (b *BucketHandle) Object(name string) *ObjectHandle {
bucket: b.name, bucket: b.name,
object: name, object: name,
acl: ACLHandle{ acl: ACLHandle{
c: b.c, c: b.c,
bucket: b.name, bucket: b.name,
object: name, object: name,
userProject: b.userProject,
}, },
gen: -1, gen: -1,
userProject: b.userProject,
} }
} }
// Attrs returns the metadata for the bucket. // Attrs returns the metadata for the bucket.
func (b *BucketHandle) Attrs(ctx context.Context) (*BucketAttrs, error) { func (b *BucketHandle) Attrs(ctx context.Context) (*BucketAttrs, error) {
req, err := b.newGetCall()
if err != nil {
return nil, err
}
var resp *raw.Bucket var resp *raw.Bucket
var err error
err = runWithRetry(ctx, func() error { err = runWithRetry(ctx, func() error {
resp, err = b.c.raw.Buckets.Get(b.name).Projection("full").Context(ctx).Do() resp, err = req.Context(ctx).Do()
return err return err
}) })
if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound {
@ -95,9 +158,49 @@ func (b *BucketHandle) Attrs(ctx context.Context) (*BucketAttrs, error) {
return newBucket(resp), nil return newBucket(resp), nil
} }
func (b *BucketHandle) newGetCall() (*raw.BucketsGetCall, error) {
req := b.c.raw.Buckets.Get(b.name).Projection("full")
setClientHeader(req.Header())
if err := applyBucketConds("BucketHandle.Attrs", b.conds, req); err != nil {
return nil, err
}
if b.userProject != "" {
req.UserProject(b.userProject)
}
return req, nil
}
func (b *BucketHandle) Update(ctx context.Context, uattrs BucketAttrsToUpdate) (*BucketAttrs, error) {
req, err := b.newPatchCall(&uattrs)
if err != nil {
return nil, err
}
// TODO(jba): retry iff metagen is set?
rb, err := req.Context(ctx).Do()
if err != nil {
return nil, err
}
return newBucket(rb), nil
}
func (b *BucketHandle) newPatchCall(uattrs *BucketAttrsToUpdate) (*raw.BucketsPatchCall, error) {
rb := uattrs.toRawBucket()
req := b.c.raw.Buckets.Patch(b.name, rb).Projection("full")
setClientHeader(req.Header())
if err := applyBucketConds("BucketHandle.Update", b.conds, req); err != nil {
return nil, err
}
if b.userProject != "" {
req.UserProject(b.userProject)
}
return req, nil
}
// BucketAttrs represents the metadata for a Google Cloud Storage bucket. // BucketAttrs represents the metadata for a Google Cloud Storage bucket.
// Read-only fields are ignored by BucketHandle.Create.
type BucketAttrs struct { type BucketAttrs struct {
// Name is the name of the bucket. // Name is the name of the bucket.
// This field is read-only.
Name string Name string
// ACL is the list of access control rules on the bucket. // ACL is the list of access control rules on the bucket.
@ -111,9 +214,10 @@ type BucketAttrs struct {
Location string Location string
// MetaGeneration is the metadata generation of the bucket. // MetaGeneration is the metadata generation of the bucket.
// This field is read-only.
MetaGeneration int64 MetaGeneration int64
// StorageClass is the storage class of the bucket. This defines // StorageClass is the default storage class of the bucket. This defines
// how objects in the bucket are stored and determines the SLA // how objects in the bucket are stored and determines the SLA
// and the cost of storage. Typical values are "MULTI_REGIONAL", // and the cost of storage. Typical values are "MULTI_REGIONAL",
// "REGIONAL", "NEARLINE", "COLDLINE", "STANDARD" and // "REGIONAL", "NEARLINE", "COLDLINE", "STANDARD" and
@ -123,11 +227,112 @@ type BucketAttrs struct {
StorageClass string StorageClass string
// Created is the creation time of the bucket. // Created is the creation time of the bucket.
// This field is read-only.
Created time.Time Created time.Time
// VersioningEnabled reports whether this bucket has versioning enabled. // VersioningEnabled reports whether this bucket has versioning enabled.
// This field is read-only.
VersioningEnabled bool VersioningEnabled bool
// Labels are the bucket's labels.
Labels map[string]string
// RequesterPays reports whether the bucket is a Requester Pays bucket.
// Clients performing operations on Requester Pays buckets must provide
// a user project (see BucketHandle.UserProject), which will be billed
// for the operations.
RequesterPays bool
// Lifecycle is the lifecycle configuration for objects in the bucket.
Lifecycle Lifecycle
}
// Lifecycle is the lifecycle configuration for objects in the bucket.
type Lifecycle struct {
Rules []LifecycleRule
}
const (
// RFC3339 date with only the date segment, used for CreatedBefore in LifecycleRule.
rfc3339Date = "2006-01-02"
// DeleteAction is a lifecycle action that deletes a live and/or archived
// objects. Takes precendence over SetStorageClass actions.
DeleteAction = "Delete"
// SetStorageClassAction changes the storage class of live and/or archived
// objects.
SetStorageClassAction = "SetStorageClass"
)
// LifecycleRule is a lifecycle configuration rule.
//
// When all the configured conditions are met by an object in the bucket, the
// configured action will automatically be taken on that object.
type LifecycleRule struct {
// Action is the action to take when all of the associated conditions are
// met.
Action LifecycleAction
// Condition is the set of conditions that must be met for the associated
// action to be taken.
Condition LifecycleCondition
}
// LifecycleAction is a lifecycle configuration action.
type LifecycleAction struct {
// Type is the type of action to take on matching objects.
//
// Acceptable values are "Delete" to delete matching objects and
// "SetStorageClass" to set the storage class defined in StorageClass on
// matching objects.
Type string
// StorageClass is the storage class to set on matching objects if the Action
// is "SetStorageClass".
StorageClass string
}
// Liveness specifies whether the object is live or not.
type Liveness int
const (
// LiveAndArchived includes both live and archived objects.
LiveAndArchived Liveness = iota
// Live specifies that the object is still live.
Live
// Archived specifies that the object is archived.
Archived
)
// LifecycleCondition is a set of conditions used to match objects and take an
// action automatically.
//
// All configured conditions must be met for the associated action to be taken.
type LifecycleCondition struct {
// AgeInDays is the age of the object in days.
AgeInDays int64
// CreatedBefore is the time the object was created.
//
// This condition is satisfied when an object is created before midnight of
// the specified date in UTC.
CreatedBefore time.Time
// Liveness specifies the object's liveness. Relevant only for versioned objects
Liveness Liveness
// MatchesStorageClasses is the condition matching the object's storage
// class.
//
// Values include "MULTI_REGIONAL", "REGIONAL", "NEARLINE", "COLDLINE",
// "STANDARD", and "DURABLE_REDUCED_AVAILABILITY".
MatchesStorageClasses []string
// NumNewerVersions is the condition matching objects with a number of newer versions.
//
// If the value is N, this condition is satisfied when there are at least N
// versions (including the live version) newer than this version of the
// object.
NumNewerVersions int64
} }
func newBucket(b *raw.Bucket) *BucketAttrs { func newBucket(b *raw.Bucket) *BucketAttrs {
@ -141,6 +346,9 @@ func newBucket(b *raw.Bucket) *BucketAttrs {
StorageClass: b.StorageClass, StorageClass: b.StorageClass,
Created: convertTime(b.TimeCreated), Created: convertTime(b.TimeCreated),
VersioningEnabled: b.Versioning != nil && b.Versioning.Enabled, VersioningEnabled: b.Versioning != nil && b.Versioning.Enabled,
Labels: b.Labels,
RequesterPays: b.Billing != nil && b.Billing.RequesterPays,
Lifecycle: toLifecycle(b.Lifecycle),
} }
acl := make([]ACLRule, len(b.Acl)) acl := make([]ACLRule, len(b.Acl))
for i, rule := range b.Acl { for i, rule := range b.Acl {
@ -174,15 +382,238 @@ func (b *BucketAttrs) toRawBucket() *raw.Bucket {
} }
} }
dACL := toRawObjectACL(b.DefaultObjectACL) dACL := toRawObjectACL(b.DefaultObjectACL)
// Copy label map.
var labels map[string]string
if len(b.Labels) > 0 {
labels = make(map[string]string, len(b.Labels))
for k, v := range b.Labels {
labels[k] = v
}
}
// Ignore VersioningEnabled if it is false. This is OK because
// we only call this method when creating a bucket, and by default
// new buckets have versioning off.
var v *raw.BucketVersioning
if b.VersioningEnabled {
v = &raw.BucketVersioning{Enabled: true}
}
var bb *raw.BucketBilling
if b.RequesterPays {
bb = &raw.BucketBilling{RequesterPays: true}
}
return &raw.Bucket{ return &raw.Bucket{
Name: b.Name, Name: b.Name,
DefaultObjectAcl: dACL, DefaultObjectAcl: dACL,
Location: b.Location, Location: b.Location,
StorageClass: b.StorageClass, StorageClass: b.StorageClass,
Acl: acl, Acl: acl,
Versioning: v,
Labels: labels,
Billing: bb,
Lifecycle: toRawLifecycle(b.Lifecycle),
} }
} }
type BucketAttrsToUpdate struct {
// VersioningEnabled, if set, updates whether the bucket uses versioning.
VersioningEnabled optional.Bool
// RequesterPays, if set, updates whether the bucket is a Requester Pays bucket.
RequesterPays optional.Bool
setLabels map[string]string
deleteLabels map[string]bool
}
// SetLabel causes a label to be added or modified when ua is used
// in a call to Bucket.Update.
func (ua *BucketAttrsToUpdate) SetLabel(name, value string) {
if ua.setLabels == nil {
ua.setLabels = map[string]string{}
}
ua.setLabels[name] = value
}
// DeleteLabel causes a label to be deleted when ua is used in a
// call to Bucket.Update.
func (ua *BucketAttrsToUpdate) DeleteLabel(name string) {
if ua.deleteLabels == nil {
ua.deleteLabels = map[string]bool{}
}
ua.deleteLabels[name] = true
}
func (ua *BucketAttrsToUpdate) toRawBucket() *raw.Bucket {
rb := &raw.Bucket{}
if ua.VersioningEnabled != nil {
rb.Versioning = &raw.BucketVersioning{
Enabled: optional.ToBool(ua.VersioningEnabled),
ForceSendFields: []string{"Enabled"},
}
}
if ua.RequesterPays != nil {
rb.Billing = &raw.BucketBilling{
RequesterPays: optional.ToBool(ua.RequesterPays),
ForceSendFields: []string{"RequesterPays"},
}
}
if ua.setLabels != nil || ua.deleteLabels != nil {
rb.Labels = map[string]string{}
for k, v := range ua.setLabels {
rb.Labels[k] = v
}
if len(rb.Labels) == 0 && len(ua.deleteLabels) > 0 {
rb.ForceSendFields = append(rb.ForceSendFields, "Labels")
}
for l := range ua.deleteLabels {
rb.NullFields = append(rb.NullFields, "Labels."+l)
}
}
return rb
}
// If returns a new BucketHandle that applies a set of preconditions.
// Preconditions already set on the BucketHandle are ignored.
// Operations on the new handle will only occur if the preconditions are
// satisfied. The only valid preconditions for buckets are MetagenerationMatch
// and MetagenerationNotMatch.
func (b *BucketHandle) If(conds BucketConditions) *BucketHandle {
b2 := *b
b2.conds = &conds
return &b2
}
// BucketConditions constrain bucket methods to act on specific metagenerations.
//
// The zero value is an empty set of constraints.
type BucketConditions struct {
// MetagenerationMatch specifies that the bucket must have the given
// metageneration for the operation to occur.
// If MetagenerationMatch is zero, it has no effect.
MetagenerationMatch int64
// MetagenerationNotMatch specifies that the bucket must not have the given
// metageneration for the operation to occur.
// If MetagenerationNotMatch is zero, it has no effect.
MetagenerationNotMatch int64
}
func (c *BucketConditions) validate(method string) error {
if *c == (BucketConditions{}) {
return fmt.Errorf("storage: %s: empty conditions", method)
}
if c.MetagenerationMatch != 0 && c.MetagenerationNotMatch != 0 {
return fmt.Errorf("storage: %s: multiple conditions specified for metageneration", method)
}
return nil
}
// UserProject returns a new BucketHandle that passes the project ID as the user
// project for all subsequent calls. Calls with a user project will be billed to that
// project rather than to the bucket's owning project.
//
// A user project is required for all operations on Requester Pays buckets.
func (b *BucketHandle) UserProject(projectID string) *BucketHandle {
b2 := *b
b2.userProject = projectID
b2.acl.userProject = projectID
b2.defaultObjectACL.userProject = projectID
return &b2
}
// applyBucketConds modifies the provided call using the conditions in conds.
// call is something that quacks like a *raw.WhateverCall.
func applyBucketConds(method string, conds *BucketConditions, call interface{}) error {
if conds == nil {
return nil
}
if err := conds.validate(method); err != nil {
return err
}
cval := reflect.ValueOf(call)
switch {
case conds.MetagenerationMatch != 0:
if !setConditionField(cval, "IfMetagenerationMatch", conds.MetagenerationMatch) {
return fmt.Errorf("storage: %s: ifMetagenerationMatch not supported", method)
}
case conds.MetagenerationNotMatch != 0:
if !setConditionField(cval, "IfMetagenerationNotMatch", conds.MetagenerationNotMatch) {
return fmt.Errorf("storage: %s: ifMetagenerationNotMatch not supported", method)
}
}
return nil
}
func toRawLifecycle(l Lifecycle) *raw.BucketLifecycle {
var rl raw.BucketLifecycle
if len(l.Rules) == 0 {
return nil
}
for _, r := range l.Rules {
rr := &raw.BucketLifecycleRule{
Action: &raw.BucketLifecycleRuleAction{
Type: r.Action.Type,
StorageClass: r.Action.StorageClass,
},
Condition: &raw.BucketLifecycleRuleCondition{
Age: r.Condition.AgeInDays,
MatchesStorageClass: r.Condition.MatchesStorageClasses,
NumNewerVersions: r.Condition.NumNewerVersions,
},
}
switch r.Condition.Liveness {
case LiveAndArchived:
rr.Condition.IsLive = nil
case Live:
rr.Condition.IsLive = googleapi.Bool(true)
case Archived:
rr.Condition.IsLive = googleapi.Bool(false)
}
if !r.Condition.CreatedBefore.IsZero() {
rr.Condition.CreatedBefore = r.Condition.CreatedBefore.Format(rfc3339Date)
}
rl.Rule = append(rl.Rule, rr)
}
return &rl
}
func toLifecycle(rl *raw.BucketLifecycle) Lifecycle {
var l Lifecycle
if rl == nil {
return l
}
for _, rr := range rl.Rule {
r := LifecycleRule{
Action: LifecycleAction{
Type: rr.Action.Type,
StorageClass: rr.Action.StorageClass,
},
Condition: LifecycleCondition{
AgeInDays: rr.Condition.Age,
MatchesStorageClasses: rr.Condition.MatchesStorageClass,
NumNewerVersions: rr.Condition.NumNewerVersions,
},
}
switch {
case rr.Condition.IsLive == nil:
r.Condition.Liveness = LiveAndArchived
case *rr.Condition.IsLive == true:
r.Condition.Liveness = Live
case *rr.Condition.IsLive == false:
r.Condition.Liveness = Archived
}
if rr.Condition.CreatedBefore != "" {
r.Condition.CreatedBefore, _ = time.Parse(rfc3339Date, rr.Condition.CreatedBefore)
}
l.Rules = append(l.Rules, r)
}
return l
}
// Objects returns an iterator over the objects in the bucket that match the Query q. // Objects returns an iterator over the objects in the bucket that match the Query q.
// If q is nil, no filtering is done. // If q is nil, no filtering is done.
func (b *BucketHandle) Objects(ctx context.Context, q *Query) *ObjectIterator { func (b *BucketHandle) Objects(ctx context.Context, q *Query) *ObjectIterator {
@ -231,11 +662,15 @@ func (it *ObjectIterator) Next() (*ObjectAttrs, error) {
func (it *ObjectIterator) fetch(pageSize int, pageToken string) (string, error) { func (it *ObjectIterator) fetch(pageSize int, pageToken string) (string, error) {
req := it.bucket.c.raw.Objects.List(it.bucket.name) req := it.bucket.c.raw.Objects.List(it.bucket.name)
setClientHeader(req.Header())
req.Projection("full") req.Projection("full")
req.Delimiter(it.query.Delimiter) req.Delimiter(it.query.Delimiter)
req.Prefix(it.query.Prefix) req.Prefix(it.query.Prefix)
req.Versions(it.query.Versions) req.Versions(it.query.Versions)
req.PageToken(pageToken) req.PageToken(pageToken)
if it.bucket.userProject != "" {
req.UserProject(it.bucket.userProject)
}
if pageSize > 0 { if pageSize > 0 {
req.MaxResults(int64(pageSize)) req.MaxResults(int64(pageSize))
} }
@ -246,6 +681,9 @@ func (it *ObjectIterator) fetch(pageSize int, pageToken string) (string, error)
return err return err
}) })
if err != nil { if err != nil {
if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound {
err = ErrBucketNotExist
}
return "", err return "", err
} }
for _, item := range resp.Items { for _, item := range resp.Items {
@ -306,6 +744,7 @@ func (it *BucketIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }
func (it *BucketIterator) fetch(pageSize int, pageToken string) (string, error) { func (it *BucketIterator) fetch(pageSize int, pageToken string) (string, error) {
req := it.client.raw.Buckets.List(it.projectID) req := it.client.raw.Buckets.List(it.projectID)
setClientHeader(req.Header())
req.Projection("full") req.Projection("full")
req.Prefix(it.Prefix) req.Prefix(it.Prefix)
req.PageToken(pageToken) req.PageToken(pageToken)

View File

@ -12,15 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package storage contains a Google Cloud Storage client.
//
// This package is experimental and may make backwards-incompatible changes.
package storage package storage
import ( import (
"errors" "errors"
"fmt" "fmt"
"reflect"
"golang.org/x/net/context" "golang.org/x/net/context"
raw "google.golang.org/api/storage/v1" raw "google.golang.org/api/storage/v1"
@ -29,6 +25,9 @@ import (
// CopierFrom creates a Copier that can copy src to dst. // CopierFrom creates a Copier that can copy src to dst.
// You can immediately call Run on the returned Copier, or // You can immediately call Run on the returned Copier, or
// you can configure it first. // you can configure it first.
//
// For Requester Pays buckets, the user project of dst is billed, unless it is empty,
// in which case the user project of src is billed.
func (dst *ObjectHandle) CopierFrom(src *ObjectHandle) *Copier { func (dst *ObjectHandle) CopierFrom(src *ObjectHandle) *Copier {
return &Copier{dst: dst, src: src} return &Copier{dst: dst, src: src}
} }
@ -46,7 +45,7 @@ type Copier struct {
RewriteToken string RewriteToken string
// ProgressFunc can be used to monitor the progress of a multi-RPC copy // ProgressFunc can be used to monitor the progress of a multi-RPC copy
// operation. If ProgressFunc is not nil and CopyFrom requires multiple // operation. If ProgressFunc is not nil and copying requires multiple
// calls to the underlying service (see // calls to the underlying service (see
// https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite), then // https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite), then
// ProgressFunc will be invoked after each call with the number of bytes of // ProgressFunc will be invoked after each call with the number of bytes of
@ -71,34 +70,27 @@ func (c *Copier) Run(ctx context.Context) (*ObjectAttrs, error) {
if err := c.dst.validate(); err != nil { if err := c.dst.validate(); err != nil {
return nil, err return nil, err
} }
var rawObject *raw.Object // Convert destination attributes to raw form, omitting the bucket.
// If any attribute was set, then we make sure the name matches the destination // If the bucket is included but name or content-type aren't, the service
// name, and we check that ContentType is non-empty so we can provide a better // returns a 400 with "Required" as the only message. Omitting the bucket
// error message than the service. // does not cause any problems.
if !reflect.DeepEqual(c.ObjectAttrs, ObjectAttrs{}) { rawObject := c.ObjectAttrs.toRawObject("")
c.ObjectAttrs.Name = c.dst.object
if c.ObjectAttrs.ContentType == "" {
return nil, errors.New("storage: Copier.ContentType must be non-empty")
}
rawObject = c.ObjectAttrs.toRawObject(c.dst.bucket)
}
for { for {
res, err := c.callRewrite(ctx, c.src, rawObject) res, err := c.callRewrite(ctx, rawObject)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if c.ProgressFunc != nil { if c.ProgressFunc != nil {
c.ProgressFunc(res.TotalBytesRewritten, res.ObjectSize) c.ProgressFunc(uint64(res.TotalBytesRewritten), uint64(res.ObjectSize))
} }
if res.Done { // Finished successfully. if res.Done { // Finished successfully.
return newObject(res.Resource), nil return newObject(res.Resource), nil
} }
} }
return nil, nil
} }
func (c *Copier) callRewrite(ctx context.Context, src *ObjectHandle, rawObj *raw.Object) (*raw.RewriteResponse, error) { func (c *Copier) callRewrite(ctx context.Context, rawObj *raw.Object) (*raw.RewriteResponse, error) {
call := c.dst.c.raw.Objects.Rewrite(src.bucket, src.object, c.dst.bucket, c.dst.object, rawObj) call := c.dst.c.raw.Objects.Rewrite(c.src.bucket, c.src.object, c.dst.bucket, c.dst.object, rawObj)
call.Context(ctx).Projection("full") call.Context(ctx).Projection("full")
if c.RewriteToken != "" { if c.RewriteToken != "" {
@ -107,6 +99,11 @@ func (c *Copier) callRewrite(ctx context.Context, src *ObjectHandle, rawObj *raw
if err := applyConds("Copy destination", c.dst.gen, c.dst.conds, call); err != nil { if err := applyConds("Copy destination", c.dst.gen, c.dst.conds, call); err != nil {
return nil, err return nil, err
} }
if c.dst.userProject != "" {
call.UserProject(c.dst.userProject)
} else if c.src.userProject != "" {
call.UserProject(c.src.userProject)
}
if err := applySourceConds(c.src.gen, c.src.conds, call); err != nil { if err := applySourceConds(c.src.gen, c.src.conds, call); err != nil {
return nil, err return nil, err
} }
@ -118,6 +115,7 @@ func (c *Copier) callRewrite(ctx context.Context, src *ObjectHandle, rawObj *raw
} }
var res *raw.RewriteResponse var res *raw.RewriteResponse
var err error var err error
setClientHeader(call.Header())
err = runWithRetry(ctx, func() error { res, err = call.Do(); return err }) err = runWithRetry(ctx, func() error { res, err = call.Do(); return err })
if err != nil { if err != nil {
return nil, err return nil, err
@ -138,6 +136,8 @@ func (dst *ObjectHandle) ComposerFrom(srcs ...*ObjectHandle) *Composer {
} }
// A Composer composes source objects into a destination object. // A Composer composes source objects into a destination object.
//
// For Requester Pays buckets, the user project of dst is billed.
type Composer struct { type Composer struct {
// ObjectAttrs are optional attributes to set on the destination object. // ObjectAttrs are optional attributes to set on the destination object.
// Any attributes must be initialized before any calls on the Composer. Nil // Any attributes must be initialized before any calls on the Composer. Nil
@ -184,11 +184,15 @@ func (c *Composer) Run(ctx context.Context) (*ObjectAttrs, error) {
if err := applyConds("ComposeFrom destination", c.dst.gen, c.dst.conds, call); err != nil { if err := applyConds("ComposeFrom destination", c.dst.gen, c.dst.conds, call); err != nil {
return nil, err return nil, err
} }
if c.dst.userProject != "" {
call.UserProject(c.dst.userProject)
}
if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil { if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil {
return nil, err return nil, err
} }
var obj *raw.Object var obj *raw.Object
var err error var err error
setClientHeader(call.Header())
err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err }) err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err })
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -23,8 +23,6 @@ All of the methods of this package use exponential backoff to retry calls
that fail with certain errors, as described in that fail with certain errors, as described in
https://cloud.google.com/storage/docs/exponential-backoff. https://cloud.google.com/storage/docs/exponential-backoff.
Note: This package is experimental and may make backwards-incompatible changes.
Creating a Client Creating a Client
@ -36,6 +34,13 @@ To start working with this package, create a client:
// TODO: Handle error. // TODO: Handle error.
} }
The client will use your default application credentials.
If you only wish to access public data, you can create
an unauthenticated client with
client, err := storage.NewClient(ctx, option.WithoutAuthentication())
Buckets Buckets
A Google Cloud Storage bucket is a collection of objects. To work with a A Google Cloud Storage bucket is a collection of objects. To work with a
@ -152,5 +157,10 @@ SignedURL for details.
// TODO: Handle error. // TODO: Handle error.
} }
fmt.Println(url) fmt.Println(url)
Authentication
See examples of authorization and authentication at
https://godoc.org/cloud.google.com/go#pkg-examples.
*/ */
package storage // import "cloud.google.com/go/storage" package storage // import "cloud.google.com/go/storage"

30
vendor/cloud.google.com/go/storage/go110.go generated vendored Normal file
View File

@ -0,0 +1,30 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 go1.10
package storage
import "google.golang.org/api/googleapi"
func shouldRetry(err error) bool {
switch e := err.(type) {
case *googleapi.Error:
// Retry on 429 and 5xx, according to
// https://cloud.google.com/storage/docs/exponential-backoff.
return e.Code == 429 || (e.Code >= 500 && e.Code < 600)
default:
return false
}
}

26
vendor/cloud.google.com/go/storage/go17.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 go1.7
package storage
import (
"context"
"net/http"
)
func withContext(r *http.Request, ctx context.Context) *http.Request {
return r.WithContext(ctx)
}

121
vendor/cloud.google.com/go/storage/iam.go generated vendored Normal file
View File

@ -0,0 +1,121 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 storage
import (
"cloud.google.com/go/iam"
"golang.org/x/net/context"
raw "google.golang.org/api/storage/v1"
iampb "google.golang.org/genproto/googleapis/iam/v1"
)
// IAM provides access to IAM access control for the bucket.
func (b *BucketHandle) IAM() *iam.Handle {
return iam.InternalNewHandleClient(&iamClient{
raw: b.c.raw,
userProject: b.userProject,
}, b.name)
}
// iamClient implements the iam.client interface.
type iamClient struct {
raw *raw.Service
userProject string
}
func (c *iamClient) Get(ctx context.Context, resource string) (*iampb.Policy, error) {
call := c.raw.Buckets.GetIamPolicy(resource)
setClientHeader(call.Header())
if c.userProject != "" {
call.UserProject(c.userProject)
}
var rp *raw.Policy
var err error
err = runWithRetry(ctx, func() error {
rp, err = call.Context(ctx).Do()
return err
})
if err != nil {
return nil, err
}
return iamFromStoragePolicy(rp), nil
}
func (c *iamClient) Set(ctx context.Context, resource string, p *iampb.Policy) error {
rp := iamToStoragePolicy(p)
call := c.raw.Buckets.SetIamPolicy(resource, rp)
setClientHeader(call.Header())
if c.userProject != "" {
call.UserProject(c.userProject)
}
return runWithRetry(ctx, func() error {
_, err := call.Context(ctx).Do()
return err
})
}
func (c *iamClient) Test(ctx context.Context, resource string, perms []string) ([]string, error) {
call := c.raw.Buckets.TestIamPermissions(resource, perms)
setClientHeader(call.Header())
if c.userProject != "" {
call.UserProject(c.userProject)
}
var res *raw.TestIamPermissionsResponse
var err error
err = runWithRetry(ctx, func() error {
res, err = call.Context(ctx).Do()
return err
})
if err != nil {
return nil, err
}
return res.Permissions, nil
}
func iamToStoragePolicy(ip *iampb.Policy) *raw.Policy {
return &raw.Policy{
Bindings: iamToStorageBindings(ip.Bindings),
Etag: string(ip.Etag),
}
}
func iamToStorageBindings(ibs []*iampb.Binding) []*raw.PolicyBindings {
var rbs []*raw.PolicyBindings
for _, ib := range ibs {
rbs = append(rbs, &raw.PolicyBindings{
Role: ib.Role,
Members: ib.Members,
})
}
return rbs
}
func iamFromStoragePolicy(rp *raw.Policy) *iampb.Policy {
return &iampb.Policy{
Bindings: iamFromStorageBindings(rp.Bindings),
Etag: []byte(rp.Etag),
}
}
func iamFromStorageBindings(rbs []*raw.PolicyBindings) []*iampb.Binding {
var ibs []*iampb.Binding
for _, rb := range rbs {
ibs = append(ibs, &iampb.Binding{
Role: rb.Role,
Members: rb.Members,
})
}
return ibs
}

View File

@ -15,32 +15,22 @@
package storage package storage
import ( import (
"cloud.google.com/go/internal"
gax "github.com/googleapis/gax-go" gax "github.com/googleapis/gax-go"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/api/googleapi"
) )
// runWithRetry calls the function until it returns nil or a non-retryable error, or // runWithRetry calls the function until it returns nil or a non-retryable error, or
// the context is done. // the context is done.
func runWithRetry(ctx context.Context, call func() error) error { func runWithRetry(ctx context.Context, call func() error) error {
var backoff gax.Backoff // use defaults for gax exponential backoff return internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) {
for { err = call()
err := call()
if err == nil { if err == nil {
return nil return true, nil
} }
e, ok := err.(*googleapi.Error) if shouldRetry(err) {
if !ok { return false, nil
return err
} }
// Retry on 429 and 5xx, according to return true, err
// https://cloud.google.com/storage/docs/exponential-backoff. })
if e.Code == 429 || (e.Code >= 500 && e.Code < 600) {
if err := gax.Sleep(ctx, backoff.Pause()); err != nil {
return err
}
continue
}
return err
}
} }

40
vendor/cloud.google.com/go/storage/not_go110.go generated vendored Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 !go1.10
package storage
import (
"net/url"
"strings"
"google.golang.org/api/googleapi"
)
func shouldRetry(err error) bool {
switch e := err.(type) {
case *googleapi.Error:
// Retry on 429 and 5xx, according to
// https://cloud.google.com/storage/docs/exponential-backoff.
return e.Code == 429 || (e.Code >= 500 && e.Code < 600)
case *url.Error:
// Retry on REFUSED_STREAM.
// Unfortunately the error type is unexported, so we resort to string
// matching.
return strings.Contains(e.Error(), "REFUSED_STREAM")
default:
return false
}
}

26
vendor/cloud.google.com/go/storage/not_go17.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 !go1.7
package storage
import (
"net/http"
)
func withContext(r *http.Request, _ interface{}) *http.Request {
// In Go 1.6 and below, ignore the context.
return r
}

179
vendor/cloud.google.com/go/storage/notifications.go generated vendored Normal file
View File

@ -0,0 +1,179 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 storage
import (
"errors"
"fmt"
"regexp"
"golang.org/x/net/context"
raw "google.golang.org/api/storage/v1"
)
// A Notification describes how to send Cloud PubSub messages when certain
// events occur in a bucket.
type Notification struct {
//The ID of the notification.
ID string
// The ID of the topic to which this subscription publishes.
TopicID string
// The ID of the project to which the topic belongs.
TopicProjectID string
// Only send notifications about listed event types. If empty, send notifications
// for all event types.
// See https://cloud.google.com/storage/docs/pubsub-notifications#events.
EventTypes []string
// If present, only apply this notification configuration to object names that
// begin with this prefix.
ObjectNamePrefix string
// An optional list of additional attributes to attach to each Cloud PubSub
// message published for this notification subscription.
CustomAttributes map[string]string
// The contents of the message payload.
// See https://cloud.google.com/storage/docs/pubsub-notifications#payload.
PayloadFormat string
}
// Values for Notification.PayloadFormat.
const (
// Send no payload with notification messages.
NoPayload = "NONE"
// Send object metadata as JSON with notification messages.
JSONPayload = "JSON_API_V1"
)
// Values for Notification.EventTypes.
const (
// Event that occurs when an object is successfully created.
ObjectFinalizeEvent = "OBJECT_FINALIZE"
// Event that occurs when the metadata of an existing object changes.
ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE"
// Event that occurs when an object is permanently deleted.
ObjectDeleteEvent = "OBJECT_DELETE"
// Event that occurs when the live version of an object becomes an
// archived version.
ObjectArchiveEvent = "OBJECT_ARCHIVE"
)
func toNotification(rn *raw.Notification) *Notification {
n := &Notification{
ID: rn.Id,
EventTypes: rn.EventTypes,
ObjectNamePrefix: rn.ObjectNamePrefix,
CustomAttributes: rn.CustomAttributes,
PayloadFormat: rn.PayloadFormat,
}
n.TopicProjectID, n.TopicID = parseNotificationTopic(rn.Topic)
return n
}
var topicRE = regexp.MustCompile("^//pubsub.googleapis.com/projects/([^/]+)/topics/([^/]+)")
// parseNotificationTopic extracts the project and topic IDs from from the full
// resource name returned by the service. If the name is malformed, it returns
// "?" for both IDs.
func parseNotificationTopic(nt string) (projectID, topicID string) {
matches := topicRE.FindStringSubmatch(nt)
if matches == nil {
return "?", "?"
}
return matches[1], matches[2]
}
func toRawNotification(n *Notification) *raw.Notification {
return &raw.Notification{
Id: n.ID,
Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s",
n.TopicProjectID, n.TopicID),
EventTypes: n.EventTypes,
ObjectNamePrefix: n.ObjectNamePrefix,
CustomAttributes: n.CustomAttributes,
PayloadFormat: string(n.PayloadFormat),
}
}
// AddNotification adds a notification to b. You must set n's TopicProjectID, TopicID
// and PayloadFormat, and must not set its ID. The other fields are all optional. The
// returned Notification's ID can be used to refer to it.
func (b *BucketHandle) AddNotification(ctx context.Context, n *Notification) (*Notification, error) {
if n.ID != "" {
return nil, errors.New("storage: AddNotification: ID must not be set")
}
if n.TopicProjectID == "" {
return nil, errors.New("storage: AddNotification: missing TopicProjectID")
}
if n.TopicID == "" {
return nil, errors.New("storage: AddNotification: missing TopicID")
}
call := b.c.raw.Notifications.Insert(b.name, toRawNotification(n))
setClientHeader(call.Header())
if b.userProject != "" {
call.UserProject(b.userProject)
}
rn, err := call.Context(ctx).Do()
if err != nil {
return nil, err
}
return toNotification(rn), nil
}
// Notifications returns all the Notifications configured for this bucket, as a map
// indexed by notification ID.
func (b *BucketHandle) Notifications(ctx context.Context) (map[string]*Notification, error) {
call := b.c.raw.Notifications.List(b.name)
setClientHeader(call.Header())
if b.userProject != "" {
call.UserProject(b.userProject)
}
var res *raw.Notifications
var err error
err = runWithRetry(ctx, func() error {
res, err = call.Context(ctx).Do()
return err
})
if err != nil {
return nil, err
}
return notificationsToMap(res.Items), nil
}
func notificationsToMap(rns []*raw.Notification) map[string]*Notification {
m := map[string]*Notification{}
for _, rn := range rns {
m[rn.Id] = toNotification(rn)
}
return m
}
// DeleteNotification deletes the notification with the given ID.
func (b *BucketHandle) DeleteNotification(ctx context.Context, id string) error {
call := b.c.raw.Notifications.Delete(b.name, id)
setClientHeader(call.Header())
if b.userProject != "" {
call.UserProject(b.userProject)
}
return call.Context(ctx).Do()
}

View File

@ -15,15 +15,29 @@
package storage package storage
import ( import (
"fmt"
"hash/crc32"
"io" "io"
) )
var crc32cTable = crc32.MakeTable(crc32.Castagnoli)
// Reader reads a Cloud Storage object. // Reader reads a Cloud Storage object.
// It implements io.Reader. // It implements io.Reader.
//
// Typically, a Reader computes the CRC of the downloaded content and compares it to
// the stored CRC, returning an error from Read if there is a mismatch. This integrity check
// is skipped if transcoding occurs. See https://cloud.google.com/storage/docs/transcoding.
type Reader struct { type Reader struct {
body io.ReadCloser body io.ReadCloser
remain, size int64 remain, size int64
contentType string contentType string
contentEncoding string
cacheControl string
checkCRC bool // should we check the CRC?
wantCRC uint32 // the CRC32c value the server sent in the header
gotCRC uint32 // running crc
checkedCRC bool // did we check the CRC? (For tests.)
} }
// Close closes the Reader. It must be called when done reading. // Close closes the Reader. It must be called when done reading.
@ -36,6 +50,19 @@ func (r *Reader) Read(p []byte) (int, error) {
if r.remain != -1 { if r.remain != -1 {
r.remain -= int64(n) r.remain -= int64(n)
} }
if r.checkCRC {
r.gotCRC = crc32.Update(r.gotCRC, crc32cTable, p[:n])
// Check CRC here. It would be natural to check it in Close, but
// everybody defers Close on the assumption that it doesn't return
// anything worth looking at.
if r.remain == 0 { // Only check if we have Content-Length.
r.checkedCRC = true
if r.gotCRC != r.wantCRC {
return n, fmt.Errorf("storage: bad CRC on read: got %d, want %d",
r.gotCRC, r.wantCRC)
}
}
}
return n, err return n, err
} }
@ -55,3 +82,13 @@ func (r *Reader) Remain() int64 {
func (r *Reader) ContentType() string { func (r *Reader) ContentType() string {
return r.contentType return r.contentType
} }
// ContentEncoding returns the content encoding of the object.
func (r *Reader) ContentEncoding() string {
return r.contentEncoding
}
// CacheControl returns the cache control of the object.
func (r *Reader) CacheControl() string {
return r.cacheControl
}

View File

@ -30,15 +30,18 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"reflect" "reflect"
"regexp"
"sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"unicode/utf8" "unicode/utf8"
"google.golang.org/api/option" "google.golang.org/api/option"
"google.golang.org/api/transport" htransport "google.golang.org/api/transport/http"
"cloud.google.com/go/internal/optional" "cloud.google.com/go/internal/optional"
"cloud.google.com/go/internal/version"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/api/googleapi" "google.golang.org/api/googleapi"
raw "google.golang.org/api/storage/v1" raw "google.golang.org/api/storage/v1"
@ -65,6 +68,12 @@ const (
ScopeReadWrite = raw.DevstorageReadWriteScope ScopeReadWrite = raw.DevstorageReadWriteScope
) )
var xGoogHeader = fmt.Sprintf("gl-go/%s gccl/%s", version.Go(), version.Repo)
func setClientHeader(headers http.Header) {
headers.Set("x-goog-api-client", xGoogHeader)
}
// Client is a client for interacting with Google Cloud Storage. // Client is a client for interacting with Google Cloud Storage.
// //
// Clients should be reused instead of created as needed. // Clients should be reused instead of created as needed.
@ -82,7 +91,7 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error
option.WithUserAgent(userAgent), option.WithUserAgent(userAgent),
} }
opts = append(o, opts...) opts = append(o, opts...)
hc, _, err := transport.NewHTTPClient(ctx, opts...) hc, ep, err := htransport.NewClient(ctx, opts...)
if err != nil { if err != nil {
return nil, fmt.Errorf("dialing: %v", err) return nil, fmt.Errorf("dialing: %v", err)
} }
@ -90,6 +99,9 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error
if err != nil { if err != nil {
return nil, fmt.Errorf("storage client: %v", err) return nil, fmt.Errorf("storage client: %v", err)
} }
if ep != "" {
rawService.BasePath = ep
}
return &Client{ return &Client{
hc: hc, hc: hc,
raw: rawService, raw: rawService,
@ -100,43 +112,13 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error
// //
// Close need not be called at program exit. // Close need not be called at program exit.
func (c *Client) Close() error { func (c *Client) Close() error {
// Set fields to nil so that subsequent uses
// will panic.
c.hc = nil c.hc = nil
c.raw = nil
return nil return nil
} }
// BucketHandle provides operations on a Google Cloud Storage bucket.
// Use Client.Bucket to get a handle.
type BucketHandle struct {
acl ACLHandle
defaultObjectACL ACLHandle
c *Client
name string
}
// Bucket returns a BucketHandle, which provides operations on the named bucket.
// This call does not perform any network operations.
//
// The supplied name must contain only lowercase letters, numbers, dashes,
// underscores, and dots. The full specification for valid bucket names can be
// found at:
// https://cloud.google.com/storage/docs/bucket-naming
func (c *Client) Bucket(name string) *BucketHandle {
return &BucketHandle{
c: c,
name: name,
acl: ACLHandle{
c: c,
bucket: name,
},
defaultObjectACL: ACLHandle{
c: c,
bucket: name,
isDefault: true,
},
}
}
// SignedURLOptions allows you to restrict the access to the signed URL. // SignedURLOptions allows you to restrict the access to the signed URL.
type SignedURLOptions struct { type SignedURLOptions struct {
// GoogleAccessID represents the authorizer of the signed URL generation. // GoogleAccessID represents the authorizer of the signed URL generation.
@ -190,7 +172,7 @@ type SignedURLOptions struct {
// Optional. // Optional.
ContentType string ContentType string
// Headers is a list of extention headers the client must provide // Headers is a list of extension headers the client must provide
// in order to use the generated signed URL. // in order to use the generated signed URL.
// Optional. // Optional.
Headers []string Headers []string
@ -199,7 +181,61 @@ type SignedURLOptions struct {
// If provided, the client should provide the exact value on the request // If provided, the client should provide the exact value on the request
// header in order to use the signed URL. // header in order to use the signed URL.
// Optional. // Optional.
MD5 []byte MD5 string
}
var (
canonicalHeaderRegexp = regexp.MustCompile(`(?i)^(x-goog-[^:]+):(.*)?$`)
excludedCanonicalHeaders = map[string]bool{
"x-goog-encryption-key": true,
"x-goog-encryption-key-sha256": true,
}
)
// sanitizeHeaders applies the specifications for canonical extension headers at
// https://cloud.google.com/storage/docs/access-control/signed-urls#about-canonical-extension-headers.
func sanitizeHeaders(hdrs []string) []string {
headerMap := map[string][]string{}
for _, hdr := range hdrs {
// No leading or trailing whitespaces.
sanitizedHeader := strings.TrimSpace(hdr)
// Only keep canonical headers, discard any others.
headerMatches := canonicalHeaderRegexp.FindStringSubmatch(sanitizedHeader)
if len(headerMatches) == 0 {
continue
}
header := strings.ToLower(strings.TrimSpace(headerMatches[1]))
if excludedCanonicalHeaders[headerMatches[1]] {
// Do not keep any deliberately excluded canonical headers when signing.
continue
}
value := strings.TrimSpace(headerMatches[2])
if len(value) > 0 {
// Remove duplicate headers by appending the values of duplicates
// in their order of appearance.
headerMap[header] = append(headerMap[header], value)
}
}
var sanitizedHeaders []string
for header, values := range headerMap {
// There should be no spaces around the colon separating the
// header name from the header value or around the values
// themselves. The values should be separated by commas.
// NOTE: The semantics for headers without a value are not clear.
// However from specifications these should be edge-cases
// anyway and we should assume that there will be no
// canonical headers using empty values. Any such headers
// are discarded at the regexp stage above.
sanitizedHeaders = append(
sanitizedHeaders,
fmt.Sprintf("%s:%s", header, strings.Join(values, ",")),
)
}
sort.Strings(sanitizedHeaders)
return sanitizedHeaders
} }
// SignedURL returns a URL for the specified object. Signed URLs allow // SignedURL returns a URL for the specified object. Signed URLs allow
@ -222,6 +258,13 @@ func SignedURL(bucket, name string, opts *SignedURLOptions) (string, error) {
if opts.Expires.IsZero() { if opts.Expires.IsZero() {
return "", errors.New("storage: missing required expires option") return "", errors.New("storage: missing required expires option")
} }
if opts.MD5 != "" {
md5, err := base64.StdEncoding.DecodeString(opts.MD5)
if err != nil || len(md5) != 16 {
return "", errors.New("storage: invalid MD5 checksum")
}
}
opts.Headers = sanitizeHeaders(opts.Headers)
signBytes := opts.SignBytes signBytes := opts.SignBytes
if opts.PrivateKey != nil { if opts.PrivateKey != nil {
@ -238,8 +281,6 @@ func SignedURL(bucket, name string, opts *SignedURLOptions) (string, error) {
sum[:], sum[:],
) )
} }
} else {
signBytes = opts.SignBytes
} }
u := &url.URL{ u := &url.URL{
@ -251,7 +292,9 @@ func SignedURL(bucket, name string, opts *SignedURLOptions) (string, error) {
fmt.Fprintf(buf, "%s\n", opts.MD5) fmt.Fprintf(buf, "%s\n", opts.MD5)
fmt.Fprintf(buf, "%s\n", opts.ContentType) fmt.Fprintf(buf, "%s\n", opts.ContentType)
fmt.Fprintf(buf, "%d\n", opts.Expires.Unix()) fmt.Fprintf(buf, "%d\n", opts.Expires.Unix())
fmt.Fprintf(buf, "%s", strings.Join(opts.Headers, "\n")) if len(opts.Headers) > 0 {
fmt.Fprintf(buf, "%s\n", strings.Join(opts.Headers, "\n"))
}
fmt.Fprintf(buf, "%s", u.String()) fmt.Fprintf(buf, "%s", u.String())
b, err := signBytes(buf.Bytes()) b, err := signBytes(buf.Bytes())
@ -272,13 +315,15 @@ func SignedURL(bucket, name string, opts *SignedURLOptions) (string, error) {
// ObjectHandle provides operations on an object in a Google Cloud Storage bucket. // ObjectHandle provides operations on an object in a Google Cloud Storage bucket.
// Use BucketHandle.Object to get a handle. // Use BucketHandle.Object to get a handle.
type ObjectHandle struct { type ObjectHandle struct {
c *Client c *Client
bucket string bucket string
object string object string
acl ACLHandle acl ACLHandle
gen int64 // a negative value indicates latest gen int64 // a negative value indicates latest
conds *Conditions conds *Conditions
encryptionKey []byte // AES-256 key encryptionKey []byte // AES-256 key
userProject string // for requester-pays buckets
readCompressed bool // Accept-Encoding: gzip
} }
// ACL provides access to the object's access control list. // ACL provides access to the object's access control list.
@ -331,11 +376,15 @@ func (o *ObjectHandle) Attrs(ctx context.Context) (*ObjectAttrs, error) {
if err := applyConds("Attrs", o.gen, o.conds, call); err != nil { if err := applyConds("Attrs", o.gen, o.conds, call); err != nil {
return nil, err return nil, err
} }
if o.userProject != "" {
call.UserProject(o.userProject)
}
if err := setEncryptionHeaders(call.Header(), o.encryptionKey, false); err != nil { if err := setEncryptionHeaders(call.Header(), o.encryptionKey, false); err != nil {
return nil, err return nil, err
} }
var obj *raw.Object var obj *raw.Object
var err error var err error
setClientHeader(call.Header())
err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err }) err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err })
if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound {
return nil, ErrObjectNotExist return nil, ErrObjectNotExist
@ -358,11 +407,17 @@ func (o *ObjectHandle) Update(ctx context.Context, uattrs ObjectAttrsToUpdate) (
var forceSendFields, nullFields []string var forceSendFields, nullFields []string
if uattrs.ContentType != nil { if uattrs.ContentType != nil {
attrs.ContentType = optional.ToString(uattrs.ContentType) attrs.ContentType = optional.ToString(uattrs.ContentType)
forceSendFields = append(forceSendFields, "ContentType") // For ContentType, sending the empty string is a no-op.
// Instead we send a null.
if attrs.ContentType == "" {
nullFields = append(nullFields, "ContentType")
} else {
forceSendFields = append(forceSendFields, "ContentType")
}
} }
if uattrs.ContentLanguage != nil { if uattrs.ContentLanguage != nil {
attrs.ContentLanguage = optional.ToString(uattrs.ContentLanguage) attrs.ContentLanguage = optional.ToString(uattrs.ContentLanguage)
// For ContentLanguage It's an error to send the empty string. // For ContentLanguage it's an error to send the empty string.
// Instead we send a null. // Instead we send a null.
if attrs.ContentLanguage == "" { if attrs.ContentLanguage == "" {
nullFields = append(nullFields, "ContentLanguage") nullFields = append(nullFields, "ContentLanguage")
@ -372,7 +427,7 @@ func (o *ObjectHandle) Update(ctx context.Context, uattrs ObjectAttrsToUpdate) (
} }
if uattrs.ContentEncoding != nil { if uattrs.ContentEncoding != nil {
attrs.ContentEncoding = optional.ToString(uattrs.ContentEncoding) attrs.ContentEncoding = optional.ToString(uattrs.ContentEncoding)
forceSendFields = append(forceSendFields, "ContentType") forceSendFields = append(forceSendFields, "ContentEncoding")
} }
if uattrs.ContentDisposition != nil { if uattrs.ContentDisposition != nil {
attrs.ContentDisposition = optional.ToString(uattrs.ContentDisposition) attrs.ContentDisposition = optional.ToString(uattrs.ContentDisposition)
@ -404,11 +459,15 @@ func (o *ObjectHandle) Update(ctx context.Context, uattrs ObjectAttrsToUpdate) (
if err := applyConds("Update", o.gen, o.conds, call); err != nil { if err := applyConds("Update", o.gen, o.conds, call); err != nil {
return nil, err return nil, err
} }
if o.userProject != "" {
call.UserProject(o.userProject)
}
if err := setEncryptionHeaders(call.Header(), o.encryptionKey, false); err != nil { if err := setEncryptionHeaders(call.Header(), o.encryptionKey, false); err != nil {
return nil, err return nil, err
} }
var obj *raw.Object var obj *raw.Object
var err error var err error
setClientHeader(call.Header())
err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err }) err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err })
if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound {
return nil, ErrObjectNotExist return nil, ErrObjectNotExist
@ -449,6 +508,11 @@ func (o *ObjectHandle) Delete(ctx context.Context) error {
if err := applyConds("Delete", o.gen, o.conds, call); err != nil { if err := applyConds("Delete", o.gen, o.conds, call); err != nil {
return err return err
} }
if o.userProject != "" {
call.UserProject(o.userProject)
}
// Encryption doesn't apply to Delete.
setClientHeader(call.Header())
err := runWithRetry(ctx, func() error { return call.Do() }) err := runWithRetry(ctx, func() error { return call.Do() })
switch e := err.(type) { switch e := err.(type) {
case nil: case nil:
@ -461,6 +525,13 @@ func (o *ObjectHandle) Delete(ctx context.Context) error {
return err return err
} }
// ReadCompressed when true causes the read to happen without decompressing.
func (o *ObjectHandle) ReadCompressed(compressed bool) *ObjectHandle {
o2 := *o
o2.readCompressed = compressed
return &o2
}
// NewReader creates a new Reader to read the contents of the // NewReader creates a new Reader to read the contents of the
// object. // object.
// ErrObjectNotExist will be returned if the object is not found. // ErrObjectNotExist will be returned if the object is not found.
@ -499,36 +570,49 @@ func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64)
if err != nil { if err != nil {
return nil, err return nil, err
} }
req = withContext(req, ctx)
if length < 0 && offset > 0 { if length < 0 && offset > 0 {
req.Header.Set("Range", fmt.Sprintf("bytes=%d-", offset)) req.Header.Set("Range", fmt.Sprintf("bytes=%d-", offset))
} else if length > 0 { } else if length > 0 {
req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+length-1)) req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+length-1))
} }
if o.userProject != "" {
req.Header.Set("X-Goog-User-Project", o.userProject)
}
if o.readCompressed {
req.Header.Set("Accept-Encoding", "gzip")
}
if err := setEncryptionHeaders(req.Header, o.encryptionKey, false); err != nil { if err := setEncryptionHeaders(req.Header, o.encryptionKey, false); err != nil {
return nil, err return nil, err
} }
var res *http.Response var res *http.Response
err = runWithRetry(ctx, func() error { res, err = o.c.hc.Do(req); return err }) err = runWithRetry(ctx, func() error {
res, err = o.c.hc.Do(req)
if err != nil {
return err
}
if res.StatusCode == http.StatusNotFound {
res.Body.Close()
return ErrObjectNotExist
}
if res.StatusCode < 200 || res.StatusCode > 299 {
body, _ := ioutil.ReadAll(res.Body)
res.Body.Close()
return &googleapi.Error{
Code: res.StatusCode,
Header: res.Header,
Body: string(body),
}
}
if offset > 0 && length != 0 && res.StatusCode != http.StatusPartialContent {
res.Body.Close()
return errors.New("storage: partial request not satisfied")
}
return nil
})
if err != nil { if err != nil {
return nil, err return nil, err
} }
if res.StatusCode == http.StatusNotFound {
res.Body.Close()
return nil, ErrObjectNotExist
}
if res.StatusCode < 200 || res.StatusCode > 299 {
body, _ := ioutil.ReadAll(res.Body)
res.Body.Close()
return nil, &googleapi.Error{
Code: res.StatusCode,
Header: res.Header,
Body: string(body),
}
}
if offset > 0 && length != 0 && res.StatusCode != http.StatusPartialContent {
res.Body.Close()
return nil, errors.New("storage: partial request not satisfied")
}
var size int64 // total size of object, even if a range was requested. var size int64 // total size of object, even if a range was requested.
if res.StatusCode == http.StatusPartialContent { if res.StatusCode == http.StatusPartialContent {
@ -551,15 +635,39 @@ func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64)
body.Close() body.Close()
body = emptyBody body = emptyBody
} }
var (
checkCRC bool
crc uint32
)
// Even if there is a CRC header, we can't compute the hash on partial data.
if remain == size {
crc, checkCRC = parseCRC32c(res)
}
return &Reader{ return &Reader{
body: body, body: body,
size: size, size: size,
remain: remain, remain: remain,
contentType: res.Header.Get("Content-Type"), contentType: res.Header.Get("Content-Type"),
contentEncoding: res.Header.Get("Content-Encoding"),
cacheControl: res.Header.Get("Cache-Control"),
wantCRC: crc,
checkCRC: checkCRC,
}, nil }, nil
} }
func parseCRC32c(res *http.Response) (uint32, bool) {
const prefix = "crc32c="
for _, spec := range res.Header["X-Goog-Hash"] {
if strings.HasPrefix(spec, prefix) {
c, err := decodeUint32(spec[len(prefix):])
if err == nil {
return c, true
}
}
}
return 0, false
}
var emptyBody = ioutil.NopCloser(strings.NewReader("")) var emptyBody = ioutil.NopCloser(strings.NewReader(""))
// NewWriter returns a storage Writer that writes to the GCS object // NewWriter returns a storage Writer that writes to the GCS object
@ -599,11 +707,10 @@ func (o *ObjectHandle) validate() error {
return nil return nil
} }
// parseKey converts the binary contents of a private key file // parseKey converts the binary contents of a private key file to an
// to an *rsa.PrivateKey. It detects whether the private key is in a // *rsa.PrivateKey. It detects whether the private key is in a PEM container or
// PEM container or not. If so, it extracts the the private key // not. If so, it extracts the private key from PEM container before
// from PEM container before conversion. It only supports PEM // conversion. It only supports PEM containers with no passphrase.
// containers with no passphrase.
func parseKey(key []byte) (*rsa.PrivateKey, error) { func parseKey(key []byte) (*rsa.PrivateKey, error) {
if block, _ := pem.Decode(key); block != nil { if block, _ := pem.Decode(key); block != nil {
key = block.Bytes key = block.Bytes
@ -647,6 +754,7 @@ func (o *ObjectAttrs) toRawObject(bucket string) *raw.Object {
ContentLanguage: o.ContentLanguage, ContentLanguage: o.ContentLanguage,
CacheControl: o.CacheControl, CacheControl: o.CacheControl,
ContentDisposition: o.ContentDisposition, ContentDisposition: o.ContentDisposition,
StorageClass: o.StorageClass,
Acl: acl, Acl: acl,
Metadata: o.Metadata, Metadata: o.Metadata,
} }
@ -690,11 +798,16 @@ type ObjectAttrs struct {
// sent in the response headers. // sent in the response headers.
ContentDisposition string ContentDisposition string
// MD5 is the MD5 hash of the object's content. This field is read-only. // MD5 is the MD5 hash of the object's content. This field is read-only,
// except when used from a Writer. If set on a Writer, the uploaded
// data is rejected if its MD5 hash does not match this field.
MD5 []byte MD5 []byte
// CRC32C is the CRC32 checksum of the object's content using // CRC32C is the CRC32 checksum of the object's content using
// the Castagnoli93 polynomial. This field is read-only. // the Castagnoli93 polynomial. This field is read-only, except when
// used from a Writer. If set on a Writer and Writer.SendCRC32C
// is true, the uploaded data is rejected if its CRC32c hash does not
// match this field.
CRC32C uint32 CRC32C uint32
// MediaLink is an URL to the object's content. This field is read-only. // MediaLink is an URL to the object's content. This field is read-only.
@ -708,21 +821,20 @@ type ObjectAttrs struct {
// This field is read-only. // This field is read-only.
Generation int64 Generation int64
// MetaGeneration is the version of the metadata for this // Metageneration is the version of the metadata for this
// object at this generation. This field is used for preconditions // object at this generation. This field is used for preconditions
// and for detecting changes in metadata. A metageneration number // and for detecting changes in metadata. A metageneration number
// is only meaningful in the context of a particular generation // is only meaningful in the context of a particular generation
// of a particular object. This field is read-only. // of a particular object. This field is read-only.
MetaGeneration int64 Metageneration int64
// StorageClass is the storage class of the bucket. // StorageClass is the storage class of the object.
// This value defines how objects in the bucket are stored and // This value defines how objects in the bucket are stored and
// determines the SLA and the cost of storage. Typical values are // determines the SLA and the cost of storage. Typical values are
// "MULTI_REGIONAL", "REGIONAL", "NEARLINE", "COLDLINE", "STANDARD" // "MULTI_REGIONAL", "REGIONAL", "NEARLINE", "COLDLINE", "STANDARD"
// and "DURABLE_REDUCED_AVAILABILITY". // and "DURABLE_REDUCED_AVAILABILITY".
// It defaults to "STANDARD", which is equivalent to "MULTI_REGIONAL" // It defaults to "STANDARD", which is equivalent to "MULTI_REGIONAL"
// or "REGIONAL" depending on the bucket's location settings. This // or "REGIONAL" depending on the bucket's location settings.
// field is read-only.
StorageClass string StorageClass string
// Created is the time the object was created. This field is read-only. // Created is the time the object was created. This field is read-only.
@ -777,39 +889,54 @@ func newObject(o *raw.Object) *ObjectAttrs {
owner = o.Owner.Entity owner = o.Owner.Entity
} }
md5, _ := base64.StdEncoding.DecodeString(o.Md5Hash) md5, _ := base64.StdEncoding.DecodeString(o.Md5Hash)
var crc32c uint32 crc32c, _ := decodeUint32(o.Crc32c)
d, err := base64.StdEncoding.DecodeString(o.Crc32c)
if err == nil && len(d) == 4 {
crc32c = uint32(d[0])<<24 + uint32(d[1])<<16 + uint32(d[2])<<8 + uint32(d[3])
}
var sha256 string var sha256 string
if o.CustomerEncryption != nil { if o.CustomerEncryption != nil {
sha256 = o.CustomerEncryption.KeySha256 sha256 = o.CustomerEncryption.KeySha256
} }
return &ObjectAttrs{ return &ObjectAttrs{
Bucket: o.Bucket, Bucket: o.Bucket,
Name: o.Name, Name: o.Name,
ContentType: o.ContentType, ContentType: o.ContentType,
ContentLanguage: o.ContentLanguage, ContentLanguage: o.ContentLanguage,
CacheControl: o.CacheControl, CacheControl: o.CacheControl,
ACL: acl, ACL: acl,
Owner: owner, Owner: owner,
ContentEncoding: o.ContentEncoding, ContentEncoding: o.ContentEncoding,
Size: int64(o.Size), ContentDisposition: o.ContentDisposition,
MD5: md5, Size: int64(o.Size),
CRC32C: crc32c, MD5: md5,
MediaLink: o.MediaLink, CRC32C: crc32c,
Metadata: o.Metadata, MediaLink: o.MediaLink,
Generation: o.Generation, Metadata: o.Metadata,
MetaGeneration: o.Metageneration, Generation: o.Generation,
StorageClass: o.StorageClass, Metageneration: o.Metageneration,
CustomerKeySHA256: sha256, StorageClass: o.StorageClass,
Created: convertTime(o.TimeCreated), CustomerKeySHA256: sha256,
Deleted: convertTime(o.TimeDeleted), Created: convertTime(o.TimeCreated),
Updated: convertTime(o.Updated), Deleted: convertTime(o.TimeDeleted),
Updated: convertTime(o.Updated),
} }
} }
// Decode a uint32 encoded in Base64 in big-endian byte order.
func decodeUint32(b64 string) (uint32, error) {
d, err := base64.StdEncoding.DecodeString(b64)
if err != nil {
return 0, err
}
if len(d) != 4 {
return 0, fmt.Errorf("storage: %q does not encode a 32-bit value", d)
}
return uint32(d[0])<<24 + uint32(d[1])<<16 + uint32(d[2])<<8 + uint32(d[3]), nil
}
// Encode a uint32 as Base64 in big-endian byte order.
func encodeUint32(u uint32) string {
b := []byte{byte(u >> 24), byte(u >> 16), byte(u >> 8), byte(u)}
return base64.StdEncoding.EncodeToString(b)
}
// Query represents a query to filter objects from a bucket. // Query represents a query to filter objects from a bucket.
type Query struct { type Query struct {
// Delimiter returns results in a directory-like fashion. // Delimiter returns results in a directory-like fashion.
@ -843,7 +970,7 @@ func (c *contentTyper) ContentType() string {
} }
// Conditions constrain methods to act on specific generations of // Conditions constrain methods to act on specific generations of
// resources. // objects.
// //
// The zero value is an empty set of constraints. Not all conditions or // The zero value is an empty set of constraints. Not all conditions or
// combinations of conditions are applicable to all methods. // combinations of conditions are applicable to all methods.

View File

@ -15,6 +15,7 @@
package storage package storage
import ( import (
"encoding/base64"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -32,6 +33,13 @@ type Writer struct {
// attributes are ignored. // attributes are ignored.
ObjectAttrs ObjectAttrs
// SendCRC specifies whether to transmit a CRC32C field. It should be set
// to true in addition to setting the Writer's CRC32C field, because zero
// is a valid CRC and normally a zero would not be transmitted.
// If a CRC32C is sent, and the data written does not match the checksum,
// the write will be rejected.
SendCRC32C bool
// ChunkSize controls the maximum number of bytes of the object that the // ChunkSize controls the maximum number of bytes of the object that the
// Writer will attempt to send to the server in a single request. Objects // Writer will attempt to send to the server in a single request. Objects
// smaller than the size will be sent in a single request, while larger // smaller than the size will be sent in a single request, while larger
@ -43,6 +51,16 @@ type Writer struct {
// must be done before the first Write call. // must be done before the first Write call.
ChunkSize int ChunkSize int
// ProgressFunc can be used to monitor the progress of a large write.
// operation. If ProgressFunc is not nil and writing requires multiple
// calls to the underlying service (see
// https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload),
// then ProgressFunc will be invoked after each call with the number of bytes of
// content copied so far.
//
// ProgressFunc should return quickly without blocking.
ProgressFunc func(int64)
ctx context.Context ctx context.Context
o *ObjectHandle o *ObjectHandle
@ -69,7 +87,7 @@ func (w *Writer) open() error {
w.opened = true w.opened = true
if w.ChunkSize < 0 { if w.ChunkSize < 0 {
return errors.New("storage: Writer.ChunkSize must non-negative") return errors.New("storage: Writer.ChunkSize must be non-negative")
} }
mediaOpts := []googleapi.MediaOption{ mediaOpts := []googleapi.MediaOption{
googleapi.ChunkSize(w.ChunkSize), googleapi.ChunkSize(w.ChunkSize),
@ -81,10 +99,20 @@ func (w *Writer) open() error {
go func() { go func() {
defer close(w.donec) defer close(w.donec)
call := w.o.c.raw.Objects.Insert(w.o.bucket, attrs.toRawObject(w.o.bucket)). rawObj := attrs.toRawObject(w.o.bucket)
if w.SendCRC32C {
rawObj.Crc32c = encodeUint32(attrs.CRC32C)
}
if w.MD5 != nil {
rawObj.Md5Hash = base64.StdEncoding.EncodeToString(w.MD5)
}
call := w.o.c.raw.Objects.Insert(w.o.bucket, rawObj).
Media(pr, mediaOpts...). Media(pr, mediaOpts...).
Projection("full"). Projection("full").
Context(w.ctx) Context(w.ctx)
if w.ProgressFunc != nil {
call.ProgressUpdater(func(n, _ int64) { w.ProgressFunc(n) })
}
if err := setEncryptionHeaders(call.Header(), w.o.encryptionKey, false); err != nil { if err := setEncryptionHeaders(call.Header(), w.o.encryptionKey, false); err != nil {
w.err = err w.err = err
pr.CloseWithError(w.err) pr.CloseWithError(w.err)
@ -93,7 +121,25 @@ func (w *Writer) open() error {
var resp *raw.Object var resp *raw.Object
err := applyConds("NewWriter", w.o.gen, w.o.conds, call) err := applyConds("NewWriter", w.o.gen, w.o.conds, call)
if err == nil { if err == nil {
err = runWithRetry(w.ctx, func() error { resp, err = call.Do(); return err }) if w.o.userProject != "" {
call.UserProject(w.o.userProject)
}
setClientHeader(call.Header())
// If the chunk size is zero, then no chunking is done on the Reader,
// which means we cannot retry: the first call will read the data, and if
// it fails, there is no way to re-read.
if w.ChunkSize == 0 {
resp, err = call.Do()
} else {
// We will only retry here if the initial POST, which obtains a URI for
// the resumable upload, fails with a retryable error. The upload itself
// has its own retry logic.
err = runWithRetry(w.ctx, func() error {
var err2 error
resp, err2 = call.Do()
return err2
})
}
} }
if err != nil { if err != nil {
w.err = err w.err = err
@ -106,6 +152,11 @@ func (w *Writer) open() error {
} }
// Write appends to w. It implements the io.Writer interface. // Write appends to w. It implements the io.Writer interface.
//
// Since writes happen asynchronously, Write may return a nil
// error even though the write failed (or will fail). Always
// use the error returned from Writer.Close to determine if
// the upload was successful.
func (w *Writer) Write(p []byte) (n int, err error) { func (w *Writer) Write(p []byte) (n int, err error) {
if w.err != nil { if w.err != nil {
return 0, w.err return 0, w.err
@ -120,7 +171,7 @@ func (w *Writer) Write(p []byte) (n int, err error) {
// Close completes the write operation and flushes any buffered data. // Close completes the write operation and flushes any buffered data.
// If Close doesn't return an error, metadata about the written object // If Close doesn't return an error, metadata about the written object
// can be retrieved by calling Object. // can be retrieved by calling Attrs.
func (w *Writer) Close() error { func (w *Writer) Close() error {
if !w.opened { if !w.opened {
if err := w.open(); err != nil { if err := w.open(); err != nil {
@ -136,6 +187,8 @@ func (w *Writer) Close() error {
// CloseWithError aborts the write operation with the provided error. // CloseWithError aborts the write operation with the provided error.
// CloseWithError always returns nil. // CloseWithError always returns nil.
//
// Deprecated: cancel the context passed to NewWriter instead.
func (w *Writer) CloseWithError(err error) error { func (w *Writer) CloseWithError(err error) error {
if !w.opened { if !w.opened {
return nil return nil

View File

@ -2,7 +2,6 @@ package pb
import ( import (
"fmt" "fmt"
"strings"
"time" "time"
) )
@ -11,12 +10,26 @@ type Units int
const ( const (
// U_NO are default units, they represent a simple value and are not formatted at all. // U_NO are default units, they represent a simple value and are not formatted at all.
U_NO Units = iota U_NO Units = iota
// U_BYTES units are formatted in a human readable way (b, Bb, Mb, ...) // U_BYTES units are formatted in a human readable way (B, KiB, MiB, ...)
U_BYTES U_BYTES
// U_BYTES_DEC units are like U_BYTES, but base 10 (B, KB, MB, ...)
U_BYTES_DEC
// U_DURATION units are formatted in a human readable way (3h14m15s) // U_DURATION units are formatted in a human readable way (3h14m15s)
U_DURATION U_DURATION
) )
const (
KiB = 1024
MiB = 1048576
GiB = 1073741824
TiB = 1099511627776
KB = 1e3
MB = 1e6
GB = 1e9
TB = 1e12
)
func Format(i int64) *formatter { func Format(i int64) *formatter {
return &formatter{n: i} return &formatter{n: i}
} }
@ -28,11 +41,6 @@ type formatter struct {
perSec bool perSec bool
} }
func (f *formatter) Value(n int64) *formatter {
f.n = n
return f
}
func (f *formatter) To(unit Units) *formatter { func (f *formatter) To(unit Units) *formatter {
f.unit = unit f.unit = unit
return f return f
@ -52,13 +60,10 @@ func (f *formatter) String() (out string) {
switch f.unit { switch f.unit {
case U_BYTES: case U_BYTES:
out = formatBytes(f.n) out = formatBytes(f.n)
case U_BYTES_DEC:
out = formatBytesDec(f.n)
case U_DURATION: case U_DURATION:
d := time.Duration(f.n) out = formatDuration(f.n)
if d > time.Hour*24 {
out = fmt.Sprintf("%dd", d/24/time.Hour)
d -= (d / time.Hour / 24) * (time.Hour * 24)
}
out = fmt.Sprintf("%s%v", out, d)
default: default:
out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n) out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n)
} }
@ -68,20 +73,46 @@ func (f *formatter) String() (out string) {
return return
} }
// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B // Convert bytes to human readable string. Like 2 MiB, 64.2 KiB, 52 B
func formatBytes(i int64) (result string) { func formatBytes(i int64) (result string) {
switch { switch {
case i > (1024 * 1024 * 1024 * 1024): case i >= TiB:
result = fmt.Sprintf("%.02f TB", float64(i)/1024/1024/1024/1024) result = fmt.Sprintf("%.02f TiB", float64(i)/TiB)
case i > (1024 * 1024 * 1024): case i >= GiB:
result = fmt.Sprintf("%.02f GB", float64(i)/1024/1024/1024) result = fmt.Sprintf("%.02f GiB", float64(i)/GiB)
case i > (1024 * 1024): case i >= MiB:
result = fmt.Sprintf("%.02f MB", float64(i)/1024/1024) result = fmt.Sprintf("%.02f MiB", float64(i)/MiB)
case i > 1024: case i >= KiB:
result = fmt.Sprintf("%.02f KB", float64(i)/1024) result = fmt.Sprintf("%.02f KiB", float64(i)/KiB)
default: default:
result = fmt.Sprintf("%d B", i) result = fmt.Sprintf("%d B", i)
} }
result = strings.Trim(result, " ") return
}
// Convert bytes to base-10 human readable string. Like 2 MB, 64.2 KB, 52 B
func formatBytesDec(i int64) (result string) {
switch {
case i >= TB:
result = fmt.Sprintf("%.02f TB", float64(i)/TB)
case i >= GB:
result = fmt.Sprintf("%.02f GB", float64(i)/GB)
case i >= MB:
result = fmt.Sprintf("%.02f MB", float64(i)/MB)
case i >= KB:
result = fmt.Sprintf("%.02f KB", float64(i)/KB)
default:
result = fmt.Sprintf("%d B", i)
}
return
}
func formatDuration(n int64) (result string) {
d := time.Duration(n)
if d > time.Hour*24 {
result = fmt.Sprintf("%dd", d/24/time.Hour)
d -= (d / time.Hour / 24) * (time.Hour * 24)
}
result = fmt.Sprintf("%s%v", result, d)
return return
} }

103
vendor/github.com/cheggaaa/pb/pb.go generated vendored
View File

@ -13,7 +13,7 @@ import (
) )
// Current version // Current version
const Version = "1.0.6" const Version = "1.0.19"
const ( const (
// Default refresh rate - 200ms // Default refresh rate - 200ms
@ -47,8 +47,6 @@ func New64(total int64) *ProgressBar {
Units: U_NO, Units: U_NO,
ManualUpdate: false, ManualUpdate: false,
finish: make(chan struct{}), finish: make(chan struct{}),
currentValue: -1,
mu: new(sync.Mutex),
} }
return pb.Format(FORMAT) return pb.Format(FORMAT)
} }
@ -67,7 +65,8 @@ func StartNew(total int) *ProgressBar {
type Callback func(out string) type Callback func(out string)
type ProgressBar struct { type ProgressBar struct {
current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278) current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278)
previous int64
Total int64 Total int64
RefreshRate time.Duration RefreshRate time.Duration
@ -91,13 +90,14 @@ type ProgressBar struct {
finish chan struct{} finish chan struct{}
isFinish bool isFinish bool
startTime time.Time startTime time.Time
startValue int64 startValue int64
currentValue int64
changeTime time.Time
prefix, postfix string prefix, postfix string
mu *sync.Mutex mu sync.Mutex
lastPrint string lastPrint string
BarStart string BarStart string
@ -112,7 +112,7 @@ type ProgressBar struct {
// Start print // Start print
func (pb *ProgressBar) Start() *ProgressBar { func (pb *ProgressBar) Start() *ProgressBar {
pb.startTime = time.Now() pb.startTime = time.Now()
pb.startValue = pb.current pb.startValue = atomic.LoadInt64(&pb.current)
if pb.Total == 0 { if pb.Total == 0 {
pb.ShowTimeLeft = false pb.ShowTimeLeft = false
pb.ShowPercent = false pb.ShowPercent = false
@ -173,7 +173,7 @@ func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter // Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
func (pb *ProgressBar) Format(format string) *ProgressBar { func (pb *ProgressBar) Format(format string) *ProgressBar {
var formatEntries []string var formatEntries []string
if len(format) == 5 { if utf8.RuneCountInString(format) == 5 {
formatEntries = strings.Split(format, "") formatEntries = strings.Split(format, "")
} else { } else {
formatEntries = strings.Split(format, "\x00") formatEntries = strings.Split(format, "\x00")
@ -222,6 +222,8 @@ func (pb *ProgressBar) Finish() {
pb.finishOnce.Do(func() { pb.finishOnce.Do(func() {
close(pb.finish) close(pb.finish)
pb.write(atomic.LoadInt64(&pb.current)) pb.write(atomic.LoadInt64(&pb.current))
pb.mu.Lock()
defer pb.mu.Unlock()
switch { switch {
case pb.Output != nil: case pb.Output != nil:
fmt.Fprintln(pb.Output) fmt.Fprintln(pb.Output)
@ -232,6 +234,13 @@ func (pb *ProgressBar) Finish() {
}) })
} }
// IsFinished return boolean
func (pb *ProgressBar) IsFinished() bool {
pb.mu.Lock()
defer pb.mu.Unlock()
return pb.isFinish
}
// End print and write string 'str' // End print and write string 'str'
func (pb *ProgressBar) FinishPrint(str string) { func (pb *ProgressBar) FinishPrint(str string) {
pb.Finish() pb.Finish()
@ -290,8 +299,12 @@ func (pb *ProgressBar) write(current int64) {
} }
// time left // time left
fromStart := time.Now().Sub(pb.startTime) pb.mu.Lock()
currentFromStart := current - pb.startValue currentFromStart := current - pb.startValue
fromStart := time.Now().Sub(pb.startTime)
lastChangeTime := pb.changeTime
fromChange := lastChangeTime.Sub(pb.startTime)
pb.mu.Unlock()
select { select {
case <-pb.finish: case <-pb.finish:
if pb.ShowFinalTime { if pb.ShowFinalTime {
@ -301,17 +314,20 @@ func (pb *ProgressBar) write(current int64) {
} }
default: default:
if pb.ShowTimeLeft && currentFromStart > 0 { if pb.ShowTimeLeft && currentFromStart > 0 {
perEntry := fromStart / time.Duration(currentFromStart) perEntry := fromChange / time.Duration(currentFromStart)
var left time.Duration var left time.Duration
if pb.Total > 0 { if pb.Total > 0 {
left = time.Duration(pb.Total-currentFromStart) * perEntry left = time.Duration(pb.Total-currentFromStart) * perEntry
left -= time.Since(lastChangeTime)
left = (left / time.Second) * time.Second left = (left / time.Second) * time.Second
} else { } else {
left = time.Duration(currentFromStart) * perEntry left = time.Duration(currentFromStart) * perEntry
left = (left / time.Second) * time.Second left = (left / time.Second) * time.Second
} }
timeLeft := Format(int64(left)).To(U_DURATION).String() if left > 0 {
timeLeftBox = fmt.Sprintf(" %s", timeLeft) timeLeft := Format(int64(left)).To(U_DURATION).String()
timeLeftBox = fmt.Sprintf(" %s", timeLeft)
}
} }
} }
@ -332,24 +348,32 @@ func (pb *ProgressBar) write(current int64) {
size := width - barWidth size := width - barWidth
if size > 0 { if size > 0 {
if pb.Total > 0 { if pb.Total > 0 {
curCount := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size))) curSize := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size)))
emptCount := size - curCount emptySize := size - curSize
barBox = pb.BarStart barBox = pb.BarStart
if emptCount < 0 { if emptySize < 0 {
emptCount = 0 emptySize = 0
} }
if curCount > size { if curSize > size {
curCount = size curSize = size
} }
if emptCount <= 0 {
barBox += strings.Repeat(pb.Current, curCount) cursorLen := escapeAwareRuneCountInString(pb.Current)
} else if curCount > 0 { if emptySize <= 0 {
barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN barBox += strings.Repeat(pb.Current, curSize/cursorLen)
} else if curSize > 0 {
cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN)
cursorRepetitions := (curSize - cursorEndLen) / cursorLen
barBox += strings.Repeat(pb.Current, cursorRepetitions)
barBox += pb.CurrentN
} }
barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd
emptyLen := escapeAwareRuneCountInString(pb.Empty)
barBox += strings.Repeat(pb.Empty, emptySize/emptyLen)
barBox += pb.BarEnd
} else { } else {
barBox = pb.BarStart
pos := size - int(current)%int(size) pos := size - int(current)%int(size)
barBox = pb.BarStart
if pos-1 > 0 { if pos-1 > 0 {
barBox += strings.Repeat(pb.Empty, pos-1) barBox += strings.Repeat(pb.Empty, pos-1)
} }
@ -364,16 +388,17 @@ func (pb *ProgressBar) write(current int64) {
// check len // check len
out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
if escapeAwareRuneCountInString(out) < width { if cl := escapeAwareRuneCountInString(out); cl < width {
end = strings.Repeat(" ", width-utf8.RuneCountInString(out)) end = strings.Repeat(" ", width-cl)
} }
// and print! // and print!
pb.mu.Lock() pb.mu.Lock()
pb.lastPrint = out + end pb.lastPrint = out + end
isFinish := pb.isFinish
pb.mu.Unlock() pb.mu.Unlock()
switch { switch {
case pb.isFinish: case isFinish:
return return
case pb.Output != nil: case pb.Output != nil:
fmt.Fprint(pb.Output, "\r"+out+end) fmt.Fprint(pb.Output, "\r"+out+end)
@ -406,10 +431,14 @@ func (pb *ProgressBar) GetWidth() int {
// Write the current state of the progressbar // Write the current state of the progressbar
func (pb *ProgressBar) Update() { func (pb *ProgressBar) Update() {
c := atomic.LoadInt64(&pb.current) c := atomic.LoadInt64(&pb.current)
if pb.AlwaysUpdate || c != pb.currentValue { p := atomic.LoadInt64(&pb.previous)
pb.write(c) if p != c {
pb.currentValue = c pb.mu.Lock()
pb.changeTime = time.Now()
pb.mu.Unlock()
atomic.StoreInt64(&pb.previous, c)
} }
pb.write(c)
if pb.AutoStat { if pb.AutoStat {
if c == 0 { if c == 0 {
pb.startTime = time.Now() pb.startTime = time.Now()
@ -420,7 +449,10 @@ func (pb *ProgressBar) Update() {
} }
} }
// String return the last bar print
func (pb *ProgressBar) String() string { func (pb *ProgressBar) String() string {
pb.mu.Lock()
defer pb.mu.Unlock()
return pb.lastPrint return pb.lastPrint
} }
@ -435,10 +467,3 @@ func (pb *ProgressBar) refresher() {
} }
} }
} }
type window struct {
Row uint16
Col uint16
Xpixel uint16
Ypixel uint16
}

View File

@ -1,8 +0,0 @@
// +build linux darwin freebsd netbsd openbsd dragonfly
// +build !appengine
package pb
import "syscall"
const sysIoctl = syscall.SYS_IOCTL

View File

@ -1,6 +0,0 @@
// +build solaris
// +build !appengine
package pb
const sysIoctl = 54

View File

@ -8,25 +8,24 @@ import (
"fmt" "fmt"
"os" "os"
"os/signal" "os/signal"
"runtime"
"sync" "sync"
"syscall" "syscall"
"unsafe"
)
const ( "golang.org/x/sys/unix"
TIOCGWINSZ = 0x5413
TIOCGWINSZ_OSX = 1074295912
) )
var tty *os.File
var ErrPoolWasStarted = errors.New("Bar pool was started") var ErrPoolWasStarted = errors.New("Bar pool was started")
var echoLocked bool var (
var echoLockMutex sync.Mutex echoLockMutex sync.Mutex
origTermStatePtr *unix.Termios
tty *os.File
)
func init() { func init() {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
var err error var err error
tty, err = os.Open("/dev/tty") tty, err = os.Open("/dev/tty")
if err != nil { if err != nil {
@ -36,64 +35,63 @@ func init() {
// terminalWidth returns width of the terminal. // terminalWidth returns width of the terminal.
func terminalWidth() (int, error) { func terminalWidth() (int, error) {
w := new(window) echoLockMutex.Lock()
tio := syscall.TIOCGWINSZ defer echoLockMutex.Unlock()
if runtime.GOOS == "darwin" {
tio = TIOCGWINSZ_OSX fd := int(tty.Fd())
}
res, _, err := syscall.Syscall(sysIoctl, ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
tty.Fd(), if err != nil {
uintptr(tio),
uintptr(unsafe.Pointer(w)),
)
if int(res) == -1 {
return 0, err return 0, err
} }
return int(w.Col), nil
}
var oldState syscall.Termios return int(ws.Col), nil
}
func lockEcho() (quit chan int, err error) { func lockEcho() (quit chan int, err error) {
echoLockMutex.Lock() echoLockMutex.Lock()
defer echoLockMutex.Unlock() defer echoLockMutex.Unlock()
if echoLocked { if origTermStatePtr != nil {
err = ErrPoolWasStarted return quit, ErrPoolWasStarted
return
}
echoLocked = true
fd := tty.Fd()
if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 {
err = fmt.Errorf("Can't get terminal settings: %v", e)
return
} }
newState := oldState fd := int(tty.Fd())
newState.Lflag &^= syscall.ECHO
newState.Lflag |= syscall.ICANON | syscall.ISIG oldTermStatePtr, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
newState.Iflag |= syscall.ICRNL if err != nil {
if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { return nil, fmt.Errorf("Can't get terminal settings: %v", err)
err = fmt.Errorf("Can't set terminal settings: %v", e)
return
} }
oldTermios := *oldTermStatePtr
newTermios := oldTermios
newTermios.Lflag &^= syscall.ECHO
newTermios.Lflag |= syscall.ICANON | syscall.ISIG
newTermios.Iflag |= syscall.ICRNL
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newTermios); err != nil {
return nil, fmt.Errorf("Can't set terminal settings: %v", err)
}
quit = make(chan int, 1) quit = make(chan int, 1)
go catchTerminate(quit) go catchTerminate(quit)
return return
} }
func unlockEcho() (err error) { func unlockEcho() error {
echoLockMutex.Lock() echoLockMutex.Lock()
defer echoLockMutex.Unlock() defer echoLockMutex.Unlock()
if !echoLocked { if origTermStatePtr == nil {
return return nil
} }
echoLocked = false
fd := tty.Fd() fd := int(tty.Fd())
if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 {
err = fmt.Errorf("Can't set terminal settings") if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, origTermStatePtr); err != nil {
return fmt.Errorf("Can't set terminal settings: %v", err)
} }
return
origTermStatePtr = nil
return nil
} }
// listen exit signals and restore terminal state // listen exit signals and restore terminal state

View File

@ -3,6 +3,7 @@
package pb package pb
import ( import (
"io"
"sync" "sync"
"time" "time"
) )
@ -19,14 +20,19 @@ func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) {
} }
type Pool struct { type Pool struct {
RefreshRate time.Duration Output io.Writer
bars []*ProgressBar RefreshRate time.Duration
quit chan int bars []*ProgressBar
finishOnce sync.Once lastBarsCount int
quit chan int
m sync.Mutex
finishOnce sync.Once
} }
// Add progress bars. // Add progress bars.
func (p *Pool) Add(pbs ...*ProgressBar) { func (p *Pool) Add(pbs ...*ProgressBar) {
p.m.Lock()
defer p.m.Unlock()
for _, bar := range pbs { for _, bar := range pbs {
bar.ManualUpdate = true bar.ManualUpdate = true
bar.NotPrint = true bar.NotPrint = true

View File

@ -8,13 +8,18 @@ import (
) )
func (p *Pool) print(first bool) bool { func (p *Pool) print(first bool) bool {
p.m.Lock()
defer p.m.Unlock()
var out string var out string
if !first { if !first {
coords, err := getCursorPos() coords, err := getCursorPos()
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
coords.Y -= int16(len(p.bars)) coords.Y -= int16(p.lastBarsCount)
if coords.Y < 0 {
coords.Y = 0
}
coords.X = 0 coords.X = 0
err = setCursorPos(coords) err = setCursorPos(coords)
@ -24,12 +29,17 @@ func (p *Pool) print(first bool) bool {
} }
isFinished := true isFinished := true
for _, bar := range p.bars { for _, bar := range p.bars {
if !bar.isFinish { if !bar.IsFinished() {
isFinished = false isFinished = false
} }
bar.Update() bar.Update()
out += fmt.Sprintf("\r%s\n", bar.String()) out += fmt.Sprintf("\r%s\n", bar.String())
} }
fmt.Print(out) if p.Output != nil {
fmt.Fprint(p.Output, out)
} else {
fmt.Print(out)
}
p.lastBarsCount = len(p.bars)
return isFinished return isFinished
} }

View File

@ -5,18 +5,25 @@ package pb
import "fmt" import "fmt"
func (p *Pool) print(first bool) bool { func (p *Pool) print(first bool) bool {
p.m.Lock()
defer p.m.Unlock()
var out string var out string
if !first { if !first {
out = fmt.Sprintf("\033[%dA", len(p.bars)) out = fmt.Sprintf("\033[%dA", p.lastBarsCount)
} }
isFinished := true isFinished := true
for _, bar := range p.bars { for _, bar := range p.bars {
if !bar.isFinish { if !bar.IsFinished() {
isFinished = false isFinished = false
} }
bar.Update() bar.Update()
out += fmt.Sprintf("\r%s\n", bar.String()) out += fmt.Sprintf("\r%s\n", bar.String())
} }
fmt.Print(out) if p.Output != nil {
fmt.Fprint(p.Output, out)
} else {
fmt.Print(out)
}
p.lastBarsCount = len(p.bars)
return isFinished return isFinished
} }

View File

@ -11,7 +11,7 @@ var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d")
func escapeAwareRuneCountInString(s string) int { func escapeAwareRuneCountInString(s string) int {
n := runewidth.StringWidth(s) n := runewidth.StringWidth(s)
for _, sm := range ctrlFinder.FindAllString(s, -1) { for _, sm := range ctrlFinder.FindAllString(s, -1) {
n -= len(sm) n -= runewidth.StringWidth(sm)
} }
return n return n
} }

View File

@ -1,7 +0,0 @@
// +build linux solaris
// +build !appengine
package pb
const ioctlReadTermios = 0x5401 // syscall.TCGETS
const ioctlWriteTermios = 0x5402 // syscall.TCSETS

13
vendor/github.com/cheggaaa/pb/termios_sysv.go generated vendored Normal file
View File

@ -0,0 +1,13 @@
// 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.
// +build linux solaris
// +build !appengine
package pb
import "golang.org/x/sys/unix"
const ioctlReadTermios = unix.TCGETS
const ioctlWriteTermios = unix.TCSETS

View File

@ -1,6 +1,5 @@
// Code generated by protoc-gen-gogo. // Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: auth.proto // source: auth.proto
// DO NOT EDIT!
/* /*
Package authpb is a generated protocol buffer package. Package authpb is a generated protocol buffer package.
@ -22,6 +21,8 @@ import (
math "math" math "math"
_ "github.com/gogo/protobuf/gogoproto"
io "io" io "io"
) )
@ -217,24 +218,6 @@ func (m *Role) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func encodeFixed64Auth(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Auth(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintAuth(dAtA []byte, offset int, v uint64) int { func encodeVarintAuth(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 { for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80) dAtA[offset] = uint8(v&0x7f | 0x80)

View File

@ -1,4 +1,4 @@
// Copyright 2013-2015 CoreOS, Inc. // Copyright 2016 The etcd Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,27 +12,5 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package semver // Package auth provides client role authentication for accessing keys in etcd.
package auth
import (
"sort"
)
type Versions []*Version
func (s Versions) Len() int {
return len(s)
}
func (s Versions) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s Versions) Less(i, j int) bool {
return s[i].LessThan(*s[j])
}
// Sort sorts the given slice of Version
func Sort(versions []*Version) {
sort.Sort(Versions(versions))
}

139
vendor/github.com/coreos/etcd/auth/jwt.go generated vendored Normal file
View File

@ -0,0 +1,139 @@
// Copyright 2017 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package auth
import (
"context"
"crypto/rsa"
"io/ioutil"
jwt "github.com/dgrijalva/jwt-go"
)
type tokenJWT struct {
signMethod string
signKey *rsa.PrivateKey
verifyKey *rsa.PublicKey
}
func (t *tokenJWT) enable() {}
func (t *tokenJWT) disable() {}
func (t *tokenJWT) invalidateUser(string) {}
func (t *tokenJWT) genTokenPrefix() (string, error) { return "", nil }
func (t *tokenJWT) info(ctx context.Context, token string, rev uint64) (*AuthInfo, bool) {
// rev isn't used in JWT, it is only used in simple token
var (
username string
revision uint64
)
parsed, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
return t.verifyKey, nil
})
switch err.(type) {
case nil:
if !parsed.Valid {
plog.Warningf("invalid jwt token: %s", token)
return nil, false
}
claims := parsed.Claims.(jwt.MapClaims)
username = claims["username"].(string)
revision = uint64(claims["revision"].(float64))
default:
plog.Warningf("failed to parse jwt token: %s", err)
return nil, false
}
return &AuthInfo{Username: username, Revision: revision}, true
}
func (t *tokenJWT) assign(ctx context.Context, username string, revision uint64) (string, error) {
// Future work: let a jwt token include permission information would be useful for
// permission checking in proxy side.
tk := jwt.NewWithClaims(jwt.GetSigningMethod(t.signMethod),
jwt.MapClaims{
"username": username,
"revision": revision,
})
token, err := tk.SignedString(t.signKey)
if err != nil {
plog.Debugf("failed to sign jwt token: %s", err)
return "", err
}
plog.Debugf("jwt token: %s", token)
return token, err
}
func prepareOpts(opts map[string]string) (jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath string, err error) {
for k, v := range opts {
switch k {
case "sign-method":
jwtSignMethod = v
case "pub-key":
jwtPubKeyPath = v
case "priv-key":
jwtPrivKeyPath = v
default:
plog.Errorf("unknown token specific option: %s", k)
return "", "", "", ErrInvalidAuthOpts
}
}
if len(jwtSignMethod) == 0 {
return "", "", "", ErrInvalidAuthOpts
}
return jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, nil
}
func newTokenProviderJWT(opts map[string]string) (*tokenJWT, error) {
jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, err := prepareOpts(opts)
if err != nil {
return nil, ErrInvalidAuthOpts
}
t := &tokenJWT{}
t.signMethod = jwtSignMethod
verifyBytes, err := ioutil.ReadFile(jwtPubKeyPath)
if err != nil {
plog.Errorf("failed to read public key (%s) for jwt: %s", jwtPubKeyPath, err)
return nil, err
}
t.verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
if err != nil {
plog.Errorf("failed to parse public key (%s): %s", jwtPubKeyPath, err)
return nil, err
}
signBytes, err := ioutil.ReadFile(jwtPrivKeyPath)
if err != nil {
plog.Errorf("failed to read private key (%s) for jwt: %s", jwtPrivKeyPath, err)
return nil, err
}
t.signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)
if err != nil {
plog.Errorf("failed to parse private key (%s): %s", jwtPrivKeyPath, err)
return nil, err
}
return t, nil
}

133
vendor/github.com/coreos/etcd/auth/range_perm_cache.go generated vendored Normal file
View File

@ -0,0 +1,133 @@
// 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 (
"github.com/coreos/etcd/auth/authpb"
"github.com/coreos/etcd/mvcc/backend"
"github.com/coreos/etcd/pkg/adt"
)
func getMergedPerms(tx backend.BatchTx, userName string) *unifiedRangePermissions {
user := getUser(tx, userName)
if user == nil {
plog.Errorf("invalid user name %s", userName)
return nil
}
readPerms := &adt.IntervalTree{}
writePerms := &adt.IntervalTree{}
for _, roleName := range user.Roles {
role := getRole(tx, roleName)
if role == nil {
continue
}
for _, perm := range role.KeyPermission {
var ivl adt.Interval
var rangeEnd []byte
if len(perm.RangeEnd) != 1 || perm.RangeEnd[0] != 0 {
rangeEnd = perm.RangeEnd
}
if len(perm.RangeEnd) != 0 {
ivl = adt.NewBytesAffineInterval(perm.Key, rangeEnd)
} else {
ivl = adt.NewBytesAffinePoint(perm.Key)
}
switch perm.PermType {
case authpb.READWRITE:
readPerms.Insert(ivl, struct{}{})
writePerms.Insert(ivl, struct{}{})
case authpb.READ:
readPerms.Insert(ivl, struct{}{})
case authpb.WRITE:
writePerms.Insert(ivl, struct{}{})
}
}
}
return &unifiedRangePermissions{
readPerms: readPerms,
writePerms: writePerms,
}
}
func checkKeyInterval(cachedPerms *unifiedRangePermissions, key, rangeEnd []byte, permtyp authpb.Permission_Type) bool {
if len(rangeEnd) == 1 && rangeEnd[0] == 0 {
rangeEnd = nil
}
ivl := adt.NewBytesAffineInterval(key, rangeEnd)
switch permtyp {
case authpb.READ:
return cachedPerms.readPerms.Contains(ivl)
case authpb.WRITE:
return cachedPerms.writePerms.Contains(ivl)
default:
plog.Panicf("unknown auth type: %v", permtyp)
}
return false
}
func checkKeyPoint(cachedPerms *unifiedRangePermissions, key []byte, permtyp authpb.Permission_Type) bool {
pt := adt.NewBytesAffinePoint(key)
switch permtyp {
case authpb.READ:
return cachedPerms.readPerms.Intersects(pt)
case authpb.WRITE:
return cachedPerms.writePerms.Intersects(pt)
default:
plog.Panicf("unknown auth type: %v", permtyp)
}
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
}
if len(rangeEnd) == 0 {
return checkKeyPoint(as.rangePermCache[userName], key, permtyp)
}
return checkKeyInterval(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 *adt.IntervalTree
writePerms *adt.IntervalTree
}

223
vendor/github.com/coreos/etcd/auth/simple_token.go generated vendored Normal file
View File

@ -0,0 +1,223 @@
// 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 (
"context"
"crypto/rand"
"fmt"
"math/big"
"strconv"
"strings"
"sync"
"time"
)
const (
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
defaultSimpleTokenLength = 16
)
// var for testing purposes
var (
simpleTokenTTL = 5 * time.Minute
simpleTokenTTLResolution = 1 * time.Second
)
type simpleTokenTTLKeeper struct {
tokens map[string]time.Time
donec chan struct{}
stopc chan struct{}
deleteTokenFunc func(string)
mu *sync.Mutex
}
func (tm *simpleTokenTTLKeeper) stop() {
select {
case tm.stopc <- struct{}{}:
case <-tm.donec:
}
<-tm.donec
}
func (tm *simpleTokenTTLKeeper) addSimpleToken(token string) {
tm.tokens[token] = time.Now().Add(simpleTokenTTL)
}
func (tm *simpleTokenTTLKeeper) resetSimpleToken(token string) {
if _, ok := tm.tokens[token]; ok {
tm.tokens[token] = time.Now().Add(simpleTokenTTL)
}
}
func (tm *simpleTokenTTLKeeper) deleteSimpleToken(token string) {
delete(tm.tokens, token)
}
func (tm *simpleTokenTTLKeeper) run() {
tokenTicker := time.NewTicker(simpleTokenTTLResolution)
defer func() {
tokenTicker.Stop()
close(tm.donec)
}()
for {
select {
case <-tokenTicker.C:
nowtime := time.Now()
tm.mu.Lock()
for t, tokenendtime := range tm.tokens {
if nowtime.After(tokenendtime) {
tm.deleteTokenFunc(t)
delete(tm.tokens, t)
}
}
tm.mu.Unlock()
case <-tm.stopc:
return
}
}
}
type tokenSimple struct {
indexWaiter func(uint64) <-chan struct{}
simpleTokenKeeper *simpleTokenTTLKeeper
simpleTokensMu sync.Mutex
simpleTokens map[string]string // token -> username
}
func (t *tokenSimple) genTokenPrefix() (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 (t *tokenSimple) assignSimpleTokenToUser(username, token string) {
t.simpleTokensMu.Lock()
defer t.simpleTokensMu.Unlock()
if t.simpleTokenKeeper == nil {
return
}
_, ok := t.simpleTokens[token]
if ok {
plog.Panicf("token %s is alredy used", token)
}
t.simpleTokens[token] = username
t.simpleTokenKeeper.addSimpleToken(token)
}
func (t *tokenSimple) invalidateUser(username string) {
if t.simpleTokenKeeper == nil {
return
}
t.simpleTokensMu.Lock()
for token, name := range t.simpleTokens {
if strings.Compare(name, username) == 0 {
delete(t.simpleTokens, token)
t.simpleTokenKeeper.deleteSimpleToken(token)
}
}
t.simpleTokensMu.Unlock()
}
func (t *tokenSimple) enable() {
delf := func(tk string) {
if username, ok := t.simpleTokens[tk]; ok {
plog.Infof("deleting token %s for user %s", tk, username)
delete(t.simpleTokens, tk)
}
}
t.simpleTokenKeeper = &simpleTokenTTLKeeper{
tokens: make(map[string]time.Time),
donec: make(chan struct{}),
stopc: make(chan struct{}),
deleteTokenFunc: delf,
mu: &t.simpleTokensMu,
}
go t.simpleTokenKeeper.run()
}
func (t *tokenSimple) disable() {
t.simpleTokensMu.Lock()
tk := t.simpleTokenKeeper
t.simpleTokenKeeper = nil
t.simpleTokens = make(map[string]string) // invalidate all tokens
t.simpleTokensMu.Unlock()
if tk != nil {
tk.stop()
}
}
func (t *tokenSimple) info(ctx context.Context, token string, revision uint64) (*AuthInfo, bool) {
if !t.isValidSimpleToken(ctx, token) {
return nil, false
}
t.simpleTokensMu.Lock()
username, ok := t.simpleTokens[token]
if ok && t.simpleTokenKeeper != nil {
t.simpleTokenKeeper.resetSimpleToken(token)
}
t.simpleTokensMu.Unlock()
return &AuthInfo{Username: username, Revision: revision}, ok
}
func (t *tokenSimple) assign(ctx context.Context, username string, rev uint64) (string, error) {
// rev isn't used in simple token, it is only used in JWT
index := ctx.Value(AuthenticateParamIndex{}).(uint64)
simpleTokenPrefix := ctx.Value(AuthenticateParamSimpleTokenPrefix{}).(string)
token := fmt.Sprintf("%s.%d", simpleTokenPrefix, index)
t.assignSimpleTokenToUser(username, token)
return token, nil
}
func (t *tokenSimple) isValidSimpleToken(ctx context.Context, token string) bool {
splitted := strings.Split(token, ".")
if len(splitted) != 2 {
return false
}
index, err := strconv.Atoi(splitted[1])
if err != nil {
return false
}
select {
case <-t.indexWaiter(uint64(index)):
return true
case <-ctx.Done():
}
return false
}
func newTokenProviderSimple(indexWaiter func(uint64) <-chan struct{}) *tokenSimple {
return &tokenSimple{
simpleTokens: make(map[string]string),
indexWaiter: indexWaiter,
}
}

1116
vendor/github.com/coreos/etcd/auth/store.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -16,11 +16,10 @@ package client
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"net/http" "net/http"
"net/url" "net/url"
"golang.org/x/net/context"
) )
type Role struct { type Role struct {

View File

@ -16,12 +16,11 @@ package client
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"golang.org/x/net/context"
) )
var ( var (

View File

@ -15,6 +15,7 @@
package client package client
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -29,8 +30,6 @@ import (
"time" "time"
"github.com/coreos/etcd/version" "github.com/coreos/etcd/version"
"golang.org/x/net/context"
) )
var ( var (
@ -372,12 +371,7 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo
if err == context.Canceled || err == context.DeadlineExceeded { if err == context.Canceled || err == context.DeadlineExceeded {
return nil, nil, err return nil, nil, err
} }
if isOneShot { } else if resp.StatusCode/100 == 5 {
return nil, nil, err
}
continue
}
if resp.StatusCode/100 == 5 {
switch resp.StatusCode { switch resp.StatusCode {
case http.StatusInternalServerError, http.StatusServiceUnavailable: case http.StatusInternalServerError, http.StatusServiceUnavailable:
// TODO: make sure this is a no leader response // TODO: make sure this is a no leader response
@ -385,10 +379,16 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo
default: default:
cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s returns server error [%s]", eps[k].String(), http.StatusText(resp.StatusCode))) cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s returns server error [%s]", eps[k].String(), http.StatusText(resp.StatusCode)))
} }
if isOneShot { err = cerr.Errors[0]
return nil, nil, cerr.Errors[0] }
if err != nil {
if !isOneShot {
continue
} }
continue c.Lock()
c.pinned = (k + 1) % leps
c.Unlock()
return nil, nil, err
} }
if k != pinned { if k != pinned {
c.Lock() c.Lock()
@ -670,8 +670,15 @@ func (r *redirectedHTTPAction) HTTPRequest(ep url.URL) *http.Request {
} }
func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL { func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL {
p := r.Perm(len(eps)) // copied from Go 1.9<= rand.Rand.Perm
neps := make([]url.URL, len(eps)) n := len(eps)
p := make([]int, n)
for i := 0; i < n; i++ {
j := r.Intn(i + 1)
p[i] = p[j]
p[j] = i
}
neps := make([]url.URL, n)
for i, k := range p { for i, k := range p {
neps[i] = eps[k] neps[i] = eps[k]
} }

View File

@ -19,9 +19,9 @@ Create a Config and exchange it for a Client:
import ( import (
"net/http" "net/http"
"context"
"github.com/coreos/etcd/client" "github.com/coreos/etcd/client"
"golang.org/x/net/context"
) )
cfg := client.Config{ cfg := client.Config{

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@ package client
//go:generate codecgen -d 1819 -r "Node|Response|Nodes" -o keys.generated.go keys.go //go:generate codecgen -d 1819 -r "Node|Response|Nodes" -o keys.generated.go keys.go
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -28,7 +29,6 @@ import (
"github.com/coreos/etcd/pkg/pathutil" "github.com/coreos/etcd/pkg/pathutil"
"github.com/ugorji/go/codec" "github.com/ugorji/go/codec"
"golang.org/x/net/context"
) )
const ( const (
@ -653,8 +653,7 @@ func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Resp
default: default:
err = unmarshalFailedKeysResponse(body) err = unmarshalFailedKeysResponse(body)
} }
return res, err
return
} }
func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response, error) { func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response, error) {

View File

@ -16,14 +16,13 @@ package client
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"golang.org/x/net/context"
"github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/pkg/types"
) )

View File

@ -15,12 +15,13 @@
package clientv3 package clientv3
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
"github.com/coreos/etcd/auth/authpb" "github.com/coreos/etcd/auth/authpb"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -100,60 +101,65 @@ type Auth interface {
} }
type auth struct { type auth struct {
remote pb.AuthClient remote pb.AuthClient
callOpts []grpc.CallOption
} }
func NewAuth(c *Client) Auth { func NewAuth(c *Client) Auth {
return &auth{remote: pb.NewAuthClient(c.ActiveConnection())} api := &auth{remote: RetryAuthClient(c)}
if c != nil {
api.callOpts = c.callOpts
}
return api
} }
func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) { func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, grpc.FailFast(false)) resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, auth.callOpts...)
return (*AuthEnableResponse)(resp), toErr(ctx, err) return (*AuthEnableResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) { func (auth *auth) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) {
resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, grpc.FailFast(false)) resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, auth.callOpts...)
return (*AuthDisableResponse)(resp), toErr(ctx, err) return (*AuthDisableResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) { 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}) resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}, auth.callOpts...)
return (*AuthUserAddResponse)(resp), toErr(ctx, err) return (*AuthUserAddResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) { func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}) resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}, auth.callOpts...)
return (*AuthUserDeleteResponse)(resp), toErr(ctx, err) return (*AuthUserDeleteResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) { 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}) resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}, auth.callOpts...)
return (*AuthUserChangePasswordResponse)(resp), toErr(ctx, err) return (*AuthUserChangePasswordResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) { 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}) resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}, auth.callOpts...)
return (*AuthUserGrantRoleResponse)(resp), toErr(ctx, err) return (*AuthUserGrantRoleResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) { func (auth *auth) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) {
resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, grpc.FailFast(false)) resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, auth.callOpts...)
return (*AuthUserGetResponse)(resp), toErr(ctx, err) return (*AuthUserGetResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) UserList(ctx context.Context) (*AuthUserListResponse, error) { func (auth *auth) UserList(ctx context.Context) (*AuthUserListResponse, error) {
resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, grpc.FailFast(false)) resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, auth.callOpts...)
return (*AuthUserListResponse)(resp), toErr(ctx, err) return (*AuthUserListResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) { 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}) resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}, auth.callOpts...)
return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err) return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) { func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) {
resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}) resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}, auth.callOpts...)
return (*AuthRoleAddResponse)(resp), toErr(ctx, err) return (*AuthRoleAddResponse)(resp), toErr(ctx, err)
} }
@ -163,27 +169,27 @@ func (auth *auth) RoleGrantPermission(ctx context.Context, name string, key, ran
RangeEnd: []byte(rangeEnd), RangeEnd: []byte(rangeEnd),
PermType: authpb.Permission_Type(permType), PermType: authpb.Permission_Type(permType),
} }
resp, err := auth.remote.RoleGrantPermission(ctx, &pb.AuthRoleGrantPermissionRequest{Name: name, Perm: perm}) resp, err := auth.remote.RoleGrantPermission(ctx, &pb.AuthRoleGrantPermissionRequest{Name: name, Perm: perm}, auth.callOpts...)
return (*AuthRoleGrantPermissionResponse)(resp), toErr(ctx, err) return (*AuthRoleGrantPermissionResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) { func (auth *auth) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) {
resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, grpc.FailFast(false)) resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, auth.callOpts...)
return (*AuthRoleGetResponse)(resp), toErr(ctx, err) return (*AuthRoleGetResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) RoleList(ctx context.Context) (*AuthRoleListResponse, error) { func (auth *auth) RoleList(ctx context.Context) (*AuthRoleListResponse, error) {
resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, grpc.FailFast(false)) resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, auth.callOpts...)
return (*AuthRoleListResponse)(resp), toErr(ctx, err) return (*AuthRoleListResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) { 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}) resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: key, RangeEnd: rangeEnd}, auth.callOpts...)
return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err) return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err)
} }
func (auth *auth) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) { func (auth *auth) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) {
resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}) resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}, auth.callOpts...)
return (*AuthRoleDeleteResponse)(resp), toErr(ctx, err) return (*AuthRoleDeleteResponse)(resp), toErr(ctx, err)
} }
@ -196,12 +202,13 @@ func StrToPermissionType(s string) (PermissionType, error) {
} }
type authenticator struct { type authenticator struct {
conn *grpc.ClientConn // conn in-use conn *grpc.ClientConn // conn in-use
remote pb.AuthClient remote pb.AuthClient
callOpts []grpc.CallOption
} }
func (auth *authenticator) authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) { 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)) resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password}, auth.callOpts...)
return (*AuthenticateResponse)(resp), toErr(ctx, err) return (*AuthenticateResponse)(resp), toErr(ctx, err)
} }
@ -209,14 +216,18 @@ func (auth *authenticator) close() {
auth.conn.Close() auth.conn.Close()
} }
func newAuthenticator(endpoint string, opts []grpc.DialOption) (*authenticator, error) { func newAuthenticator(endpoint string, opts []grpc.DialOption, c *Client) (*authenticator, error) {
conn, err := grpc.Dial(endpoint, opts...) conn, err := grpc.Dial(endpoint, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &authenticator{ api := &authenticator{
conn: conn, conn: conn,
remote: pb.NewAuthClient(conn), remote: pb.NewAuthClient(conn),
}, nil }
if c != nil {
api.callOpts = c.callOpts
}
return api, nil
} }

View File

@ -1,356 +0,0 @@
// 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"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
// ErrNoAddrAvilable is returned by Get() when the balancer does not have
// any active connection to endpoints at the time.
// This error is returned only when opts.BlockingWait is true.
var ErrNoAddrAvilable = grpc.Errorf(codes.Unavailable, "there is no address available")
// simpleBalancer does the bare minimum to expose multiple eps
// to the grpc reconnection code path
type simpleBalancer struct {
// addrs are the client's endpoints for grpc
addrs []grpc.Address
// notifyCh notifies grpc of the set of addresses for connecting
notifyCh chan []grpc.Address
// readyc closes once the first connection is up
readyc chan struct{}
readyOnce sync.Once
// mu protects upEps, pinAddr, and connectingAddr
mu sync.RWMutex
// upc closes when upEps transitions from empty to non-zero or the balancer closes.
upc chan struct{}
// downc closes when grpc calls down() on pinAddr
downc chan struct{}
// stopc is closed to signal updateNotifyLoop should stop.
stopc chan struct{}
// donec closes when all goroutines are exited
donec chan struct{}
// updateAddrsC notifies updateNotifyLoop to update addrs.
updateAddrsC chan struct{}
// grpc issues TLS cert checks using the string passed into dial so
// that string must be the host. To recover the full scheme://host URL,
// have a map from hosts to the original endpoint.
host2ep map[string]string
// pinAddr is the currently pinned address; set to the empty string on
// intialization and shutdown.
pinAddr string
closed bool
}
func newSimpleBalancer(eps []string) *simpleBalancer {
notifyCh := make(chan []grpc.Address, 1)
addrs := make([]grpc.Address, len(eps))
for i := range eps {
addrs[i].Addr = getHost(eps[i])
}
sb := &simpleBalancer{
addrs: addrs,
notifyCh: notifyCh,
readyc: make(chan struct{}),
upc: make(chan struct{}),
stopc: make(chan struct{}),
downc: make(chan struct{}),
donec: make(chan struct{}),
updateAddrsC: make(chan struct{}, 1),
host2ep: getHost2ep(eps),
}
close(sb.downc)
go sb.updateNotifyLoop()
return sb
}
func (b *simpleBalancer) Start(target string, config grpc.BalancerConfig) error { return nil }
func (b *simpleBalancer) ConnectNotify() <-chan struct{} {
b.mu.Lock()
defer b.mu.Unlock()
return b.upc
}
func (b *simpleBalancer) getEndpoint(host string) string {
b.mu.Lock()
defer b.mu.Unlock()
return b.host2ep[host]
}
func getHost2ep(eps []string) map[string]string {
hm := make(map[string]string, len(eps))
for i := range eps {
_, host, _ := parseEndpoint(eps[i])
hm[host] = eps[i]
}
return hm
}
func (b *simpleBalancer) updateAddrs(eps []string) {
np := getHost2ep(eps)
b.mu.Lock()
match := len(np) == len(b.host2ep)
for k, v := range np {
if b.host2ep[k] != v {
match = false
break
}
}
if match {
// same endpoints, so no need to update address
b.mu.Unlock()
return
}
b.host2ep = np
addrs := make([]grpc.Address, 0, len(eps))
for i := range eps {
addrs = append(addrs, grpc.Address{Addr: getHost(eps[i])})
}
b.addrs = addrs
// updating notifyCh can trigger new connections,
// only update addrs if all connections are down
// or addrs does not include pinAddr.
update := !hasAddr(addrs, b.pinAddr)
b.mu.Unlock()
if update {
select {
case b.updateAddrsC <- struct{}{}:
case <-b.stopc:
}
}
}
func hasAddr(addrs []grpc.Address, targetAddr string) bool {
for _, addr := range addrs {
if targetAddr == addr.Addr {
return true
}
}
return false
}
func (b *simpleBalancer) updateNotifyLoop() {
defer close(b.donec)
for {
b.mu.RLock()
upc, downc, addr := b.upc, b.downc, b.pinAddr
b.mu.RUnlock()
// downc or upc should be closed
select {
case <-downc:
downc = nil
default:
}
select {
case <-upc:
upc = nil
default:
}
switch {
case downc == nil && upc == nil:
// stale
select {
case <-b.stopc:
return
default:
}
case downc == nil:
b.notifyAddrs()
select {
case <-upc:
case <-b.updateAddrsC:
b.notifyAddrs()
case <-b.stopc:
return
}
case upc == nil:
select {
// close connections that are not the pinned address
case b.notifyCh <- []grpc.Address{{Addr: addr}}:
case <-downc:
case <-b.stopc:
return
}
select {
case <-downc:
case <-b.updateAddrsC:
case <-b.stopc:
return
}
b.notifyAddrs()
}
}
}
func (b *simpleBalancer) notifyAddrs() {
b.mu.RLock()
addrs := b.addrs
b.mu.RUnlock()
select {
case b.notifyCh <- addrs:
case <-b.stopc:
}
}
func (b *simpleBalancer) Up(addr grpc.Address) func(error) {
b.mu.Lock()
defer b.mu.Unlock()
// gRPC might call Up after it called Close. We add this check
// to "fix" it up at application layer. Or our simplerBalancer
// might panic since b.upc is closed.
if b.closed {
return func(err error) {}
}
// gRPC might call Up on a stale address.
// Prevent updating pinAddr with a stale address.
if !hasAddr(b.addrs, addr.Addr) {
return func(err error) {}
}
if b.pinAddr != "" {
return func(err error) {}
}
// notify waiting Get()s and pin first connected address
close(b.upc)
b.downc = make(chan struct{})
b.pinAddr = addr.Addr
// notify client that a connection is up
b.readyOnce.Do(func() { close(b.readyc) })
return func(err error) {
b.mu.Lock()
b.upc = make(chan struct{})
close(b.downc)
b.pinAddr = ""
b.mu.Unlock()
}
}
func (b *simpleBalancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (grpc.Address, func(), error) {
var (
addr string
closed bool
)
// If opts.BlockingWait is false (for fail-fast RPCs), it should return
// an address it has notified via Notify immediately instead of blocking.
if !opts.BlockingWait {
b.mu.RLock()
closed = b.closed
addr = b.pinAddr
b.mu.RUnlock()
if closed {
return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
}
if addr == "" {
return grpc.Address{Addr: ""}, nil, ErrNoAddrAvilable
}
return grpc.Address{Addr: addr}, func() {}, nil
}
for {
b.mu.RLock()
ch := b.upc
b.mu.RUnlock()
select {
case <-ch:
case <-b.donec:
return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
case <-ctx.Done():
return grpc.Address{Addr: ""}, nil, ctx.Err()
}
b.mu.RLock()
closed = b.closed
addr = b.pinAddr
b.mu.RUnlock()
// Close() which sets b.closed = true can be called before Get(), Get() must exit if balancer is closed.
if closed {
return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
}
if addr != "" {
break
}
}
return grpc.Address{Addr: addr}, func() {}, nil
}
func (b *simpleBalancer) Notify() <-chan []grpc.Address { return b.notifyCh }
func (b *simpleBalancer) Close() error {
b.mu.Lock()
// In case gRPC calls close twice. TODO: remove the checking
// when we are sure that gRPC wont call close twice.
if b.closed {
b.mu.Unlock()
<-b.donec
return nil
}
b.closed = true
close(b.stopc)
b.pinAddr = ""
// In the case of following scenario:
// 1. upc is not closed; no pinned address
// 2. client issues an rpc, calling invoke(), which calls Get(), enters for loop, blocks
// 3. clientconn.Close() calls balancer.Close(); closed = true
// 4. for loop in Get() never exits since ctx is the context passed in by the client and may not be canceled
// we must close upc so Get() exits from blocking on upc
select {
case <-b.upc:
default:
// terminate all waiting Get()s
close(b.upc)
}
b.mu.Unlock()
// wait for updateNotifyLoop to finish
<-b.donec
close(b.notifyCh)
return nil
}
func getHost(ep string) string {
url, uerr := url.Parse(ep)
if uerr != nil || !strings.Contains(ep, "://") {
return ep
}
return url.Host
}

View File

@ -15,6 +15,7 @@
package clientv3 package clientv3
import ( import (
"context"
"crypto/tls" "crypto/tls"
"errors" "errors"
"fmt" "fmt"
@ -27,11 +28,12 @@ import (
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
) )
var ( var (
@ -51,21 +53,22 @@ type Client struct {
conn *grpc.ClientConn conn *grpc.ClientConn
dialerrc chan error dialerrc chan error
cfg Config cfg Config
creds *credentials.TransportCredentials creds *credentials.TransportCredentials
balancer *simpleBalancer balancer *healthBalancer
retryWrapper retryRpcFunc mu *sync.Mutex
retryAuthWrapper retryRpcFunc
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc
// Username is a username for authentication // Username is a user name for authentication.
Username string Username string
// Password is a password for authentication // Password is a password for authentication.
Password string Password string
// tokenCred is an instance of WithPerRPCCredentials()'s argument // tokenCred is an instance of WithPerRPCCredentials()'s argument
tokenCred *authTokenCredential tokenCred *authTokenCredential
callOpts []grpc.CallOption
} }
// New creates a new etcdv3 client from a given configuration. // New creates a new etcdv3 client from a given configuration.
@ -116,8 +119,23 @@ func (c *Client) Endpoints() (eps []string) {
// SetEndpoints updates client's endpoints. // SetEndpoints updates client's endpoints.
func (c *Client) SetEndpoints(eps ...string) { func (c *Client) SetEndpoints(eps ...string) {
c.mu.Lock()
c.cfg.Endpoints = eps c.cfg.Endpoints = eps
c.balancer.updateAddrs(eps) c.mu.Unlock()
c.balancer.updateAddrs(eps...)
// updating notifyCh can trigger new connections,
// need update addrs if all connections are down
// or addrs does not include pinAddr.
c.balancer.mu.RLock()
update := !hasAddr(c.balancer.addrs, c.balancer.pinAddr)
c.balancer.mu.RUnlock()
if update {
select {
case c.balancer.updateAddrsC <- notifyNext:
case <-c.balancer.stopc:
}
}
} }
// Sync synchronizes client's endpoints with the known endpoints from the etcd membership. // Sync synchronizes client's endpoints with the known endpoints from the etcd membership.
@ -144,8 +162,10 @@ func (c *Client) autoSync() {
case <-c.ctx.Done(): case <-c.ctx.Done():
return return
case <-time.After(c.cfg.AutoSyncInterval): case <-time.After(c.cfg.AutoSyncInterval):
ctx, _ := context.WithTimeout(c.ctx, 5*time.Second) ctx, cancel := context.WithTimeout(c.ctx, 5*time.Second)
if err := c.Sync(ctx); err != nil && err != c.ctx.Err() { err := c.Sync(ctx)
cancel()
if err != nil && err != c.ctx.Err() {
logger.Println("Auto sync endpoints failed:", err) logger.Println("Auto sync endpoints failed:", err)
} }
} }
@ -174,7 +194,7 @@ func parseEndpoint(endpoint string) (proto string, host string, scheme string) {
host = endpoint host = endpoint
url, uerr := url.Parse(endpoint) url, uerr := url.Parse(endpoint)
if uerr != nil || !strings.Contains(endpoint, "://") { if uerr != nil || !strings.Contains(endpoint, "://") {
return return proto, host, scheme
} }
scheme = url.Scheme scheme = url.Scheme
@ -188,7 +208,7 @@ func parseEndpoint(endpoint string) (proto string, host string, scheme string) {
default: default:
proto, host = "", "" proto, host = "", ""
} }
return return proto, host, scheme
} }
func (c *Client) processCreds(scheme string) (creds *credentials.TransportCredentials) { func (c *Client) processCreds(scheme string) (creds *credentials.TransportCredentials) {
@ -207,7 +227,7 @@ func (c *Client) processCreds(scheme string) (creds *credentials.TransportCreden
default: default:
creds = nil creds = nil
} }
return return creds
} }
// dialSetupOpts gives the dial opts prior to any authentication // dialSetupOpts gives the dial opts prior to any authentication
@ -215,10 +235,17 @@ func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOption) (opts
if c.cfg.DialTimeout > 0 { if c.cfg.DialTimeout > 0 {
opts = []grpc.DialOption{grpc.WithTimeout(c.cfg.DialTimeout)} opts = []grpc.DialOption{grpc.WithTimeout(c.cfg.DialTimeout)}
} }
if c.cfg.DialKeepAliveTime > 0 {
params := keepalive.ClientParameters{
Time: c.cfg.DialKeepAliveTime,
Timeout: c.cfg.DialKeepAliveTimeout,
}
opts = append(opts, grpc.WithKeepaliveParams(params))
}
opts = append(opts, dopts...) opts = append(opts, dopts...)
f := func(host string, t time.Duration) (net.Conn, error) { f := func(host string, t time.Duration) (net.Conn, error) {
proto, host, _ := parseEndpoint(c.balancer.getEndpoint(host)) proto, host, _ := parseEndpoint(c.balancer.endpoint(host))
if host == "" && endpoint != "" { if host == "" && endpoint != "" {
// dialing an endpoint not in the balancer; use // dialing an endpoint not in the balancer; use
// endpoint passed into dial // endpoint passed into dial
@ -270,7 +297,7 @@ func (c *Client) getToken(ctx context.Context) error {
endpoint := c.cfg.Endpoints[i] endpoint := c.cfg.Endpoints[i]
host := getHost(endpoint) host := getHost(endpoint)
// use dial options without dopts to avoid reusing the client balancer // use dial options without dopts to avoid reusing the client balancer
auth, err = newAuthenticator(host, c.dialSetupOpts(endpoint)) auth, err = newAuthenticator(host, c.dialSetupOpts(endpoint), c)
if err != nil { if err != nil {
continue continue
} }
@ -311,7 +338,7 @@ func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grpc.ClientCo
if err != nil { if err != nil {
if toErr(ctx, err) != rpctypes.ErrAuthNotEnabled { if toErr(ctx, err) != rpctypes.ErrAuthNotEnabled {
if err == ctx.Err() && ctx.Err() != c.ctx.Err() { if err == ctx.Err() && ctx.Err() != c.ctx.Err() {
err = grpc.ErrClientConnTimeout err = context.DeadlineExceeded
} }
return nil, err return nil, err
} }
@ -360,15 +387,37 @@ func newClient(cfg *Config) (*Client, error) {
creds: creds, creds: creds,
ctx: ctx, ctx: ctx,
cancel: cancel, cancel: cancel,
mu: new(sync.Mutex),
callOpts: defaultCallOpts,
} }
if cfg.Username != "" && cfg.Password != "" { if cfg.Username != "" && cfg.Password != "" {
client.Username = cfg.Username client.Username = cfg.Username
client.Password = cfg.Password client.Password = cfg.Password
} }
if cfg.MaxCallSendMsgSize > 0 || cfg.MaxCallRecvMsgSize > 0 {
if cfg.MaxCallRecvMsgSize > 0 && cfg.MaxCallSendMsgSize > cfg.MaxCallRecvMsgSize {
return nil, fmt.Errorf("gRPC message recv limit (%d bytes) must be greater than send limit (%d bytes)", cfg.MaxCallRecvMsgSize, cfg.MaxCallSendMsgSize)
}
callOpts := []grpc.CallOption{
defaultFailFast,
defaultMaxCallSendMsgSize,
defaultMaxCallRecvMsgSize,
}
if cfg.MaxCallSendMsgSize > 0 {
callOpts[1] = grpc.MaxCallSendMsgSize(cfg.MaxCallSendMsgSize)
}
if cfg.MaxCallRecvMsgSize > 0 {
callOpts[2] = grpc.MaxCallRecvMsgSize(cfg.MaxCallRecvMsgSize)
}
client.callOpts = callOpts
}
client.balancer = newHealthBalancer(cfg.Endpoints, cfg.DialTimeout, func(ep string) (bool, error) {
return grpcHealthCheck(client, ep)
})
client.balancer = newSimpleBalancer(cfg.Endpoints)
// use Endpoints[0] so that for https:// without any tls config given, then // use Endpoints[0] so that for https:// without any tls config given, then
// grpc will assume the ServerName is in the endpoint. // grpc will assume the certificate server name is the endpoint host.
conn, err := client.dial(cfg.Endpoints[0], grpc.WithBalancer(client.balancer)) conn, err := client.dial(cfg.Endpoints[0], grpc.WithBalancer(client.balancer))
if err != nil { if err != nil {
client.cancel() client.cancel()
@ -376,21 +425,19 @@ func newClient(cfg *Config) (*Client, error) {
return nil, err return nil, err
} }
client.conn = conn client.conn = conn
client.retryWrapper = client.newRetryWrapper()
client.retryAuthWrapper = client.newAuthRetryWrapper()
// wait for a connection // wait for a connection
if cfg.DialTimeout > 0 { if cfg.DialTimeout > 0 {
hasConn := false hasConn := false
waitc := time.After(cfg.DialTimeout) waitc := time.After(cfg.DialTimeout)
select { select {
case <-client.balancer.readyc: case <-client.balancer.ready():
hasConn = true hasConn = true
case <-ctx.Done(): case <-ctx.Done():
case <-waitc: case <-waitc:
} }
if !hasConn { if !hasConn {
err := grpc.ErrClientConnTimeout err := context.DeadlineExceeded
select { select {
case err = <-client.dialerrc: case err = <-client.dialerrc:
default: default:
@ -425,7 +472,7 @@ func (c *Client) checkVersion() (err error) {
errc := make(chan error, len(c.cfg.Endpoints)) errc := make(chan error, len(c.cfg.Endpoints))
ctx, cancel := context.WithCancel(c.ctx) ctx, cancel := context.WithCancel(c.ctx)
if c.cfg.DialTimeout > 0 { if c.cfg.DialTimeout > 0 {
ctx, _ = context.WithTimeout(ctx, c.cfg.DialTimeout) ctx, cancel = context.WithTimeout(ctx, c.cfg.DialTimeout)
} }
wg.Add(len(c.cfg.Endpoints)) wg.Add(len(c.cfg.Endpoints))
for _, ep := range c.cfg.Endpoints { for _, ep := range c.cfg.Endpoints {
@ -440,7 +487,7 @@ func (c *Client) checkVersion() (err error) {
vs := strings.Split(resp.Version, ".") vs := strings.Split(resp.Version, ".")
maj, min := 0, 0 maj, min := 0, 0
if len(vs) >= 2 { if len(vs) >= 2 {
maj, rerr = strconv.Atoi(vs[0]) maj, _ = strconv.Atoi(vs[0])
min, rerr = strconv.Atoi(vs[1]) min, rerr = strconv.Atoi(vs[1])
} }
if maj < 3 || (maj == 3 && min < 2) { if maj < 3 || (maj == 3 && min < 2) {
@ -472,14 +519,14 @@ func isHaltErr(ctx context.Context, err error) bool {
if err == nil { if err == nil {
return false return false
} }
code := grpc.Code(err) ev, _ := status.FromError(err)
// Unavailable codes mean the system will be right back. // Unavailable codes mean the system will be right back.
// (e.g., can't connect, lost leader) // (e.g., can't connect, lost leader)
// Treat Internal codes as if something failed, leaving the // Treat Internal codes as if something failed, leaving the
// system in an inconsistent state, but retrying could make progress. // system in an inconsistent state, but retrying could make progress.
// (e.g., failed in middle of send, corrupted frame) // (e.g., failed in middle of send, corrupted frame)
// TODO: are permanent Internal errors possible from grpc? // TODO: are permanent Internal errors possible from grpc?
return code != codes.Unavailable && code != codes.Internal return ev.Code() != codes.Unavailable && ev.Code() != codes.Internal
} }
func toErr(ctx context.Context, err error) error { func toErr(ctx context.Context, err error) error {
@ -490,7 +537,8 @@ func toErr(ctx context.Context, err error) error {
if _, ok := err.(rpctypes.EtcdError); ok { if _, ok := err.(rpctypes.EtcdError); ok {
return err return err
} }
code := grpc.Code(err) ev, _ := status.FromError(err)
code := ev.Code()
switch code { switch code {
case codes.DeadlineExceeded: case codes.DeadlineExceeded:
fallthrough fallthrough
@ -499,7 +547,6 @@ func toErr(ctx context.Context, err error) error {
err = ctx.Err() err = ctx.Err()
} }
case codes.Unavailable: case codes.Unavailable:
err = ErrNoAvailableEndpoints
case codes.FailedPrecondition: case codes.FailedPrecondition:
err = grpc.ErrClientConnClosing err = grpc.ErrClientConnClosing
} }

View File

@ -15,8 +15,10 @@
package clientv3 package clientv3
import ( import (
"context"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -43,20 +45,29 @@ type Cluster interface {
} }
type cluster struct { type cluster struct {
remote pb.ClusterClient remote pb.ClusterClient
callOpts []grpc.CallOption
} }
func NewCluster(c *Client) Cluster { func NewCluster(c *Client) Cluster {
return &cluster{remote: RetryClusterClient(c)} api := &cluster{remote: RetryClusterClient(c)}
if c != nil {
api.callOpts = c.callOpts
}
return api
} }
func NewClusterFromClusterClient(remote pb.ClusterClient) Cluster { func NewClusterFromClusterClient(remote pb.ClusterClient, c *Client) Cluster {
return &cluster{remote: remote} api := &cluster{remote: remote}
if c != nil {
api.callOpts = c.callOpts
}
return api
} }
func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) { func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) {
r := &pb.MemberAddRequest{PeerURLs: peerAddrs} r := &pb.MemberAddRequest{PeerURLs: peerAddrs}
resp, err := c.remote.MemberAdd(ctx, r) resp, err := c.remote.MemberAdd(ctx, r, c.callOpts...)
if err != nil { if err != nil {
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
@ -65,7 +76,7 @@ func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAdd
func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error) { func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error) {
r := &pb.MemberRemoveRequest{ID: id} r := &pb.MemberRemoveRequest{ID: id}
resp, err := c.remote.MemberRemove(ctx, r) resp, err := c.remote.MemberRemove(ctx, r, c.callOpts...)
if err != nil { if err != nil {
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
@ -74,27 +85,19 @@ func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveRes
func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) { func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) {
// it is safe to retry on update. // it is safe to retry on update.
for { r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs}
r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs} resp, err := c.remote.MemberUpdate(ctx, r, c.callOpts...)
resp, err := c.remote.MemberUpdate(ctx, r, grpc.FailFast(false)) if err == nil {
if err == nil { return (*MemberUpdateResponse)(resp), nil
return (*MemberUpdateResponse)(resp), nil
}
if isHaltErr(ctx, err) {
return nil, toErr(ctx, err)
}
} }
return nil, toErr(ctx, err)
} }
func (c *cluster) MemberList(ctx context.Context) (*MemberListResponse, error) { func (c *cluster) MemberList(ctx context.Context) (*MemberListResponse, error) {
// it is safe to retry on list. // it is safe to retry on list.
for { resp, err := c.remote.MemberList(ctx, &pb.MemberListRequest{}, c.callOpts...)
resp, err := c.remote.MemberList(ctx, &pb.MemberListRequest{}, grpc.FailFast(false)) if err == nil {
if err == nil { return (*MemberListResponse)(resp), nil
return (*MemberListResponse)(resp), nil
}
if isHaltErr(ctx, err) {
return nil, toErr(ctx, err)
}
} }
return nil, toErr(ctx, err)
} }

View File

@ -44,10 +44,8 @@ func (op CompactOp) toRequest() *pb.CompactionRequest {
return &pb.CompactionRequest{Revision: op.revision, Physical: op.physical} return &pb.CompactionRequest{Revision: op.revision, Physical: op.physical}
} }
// WithCompactPhysical makes compact RPC call wait until // WithCompactPhysical makes Compact wait until all compacted entries are
// the compaction is physically applied to the local database // removed from the etcd server's storage.
// such that compacted entries are totally removed from the
// backend database.
func WithCompactPhysical() CompactOption { func WithCompactPhysical() CompactOption {
return func(op *CompactOp) { op.physical = true } return func(op *CompactOp) { op.physical = true }
} }

View File

@ -60,6 +60,8 @@ func Compare(cmp Cmp, result string, v interface{}) Cmp {
cmp.TargetUnion = &pb.Compare_CreateRevision{CreateRevision: mustInt64(v)} cmp.TargetUnion = &pb.Compare_CreateRevision{CreateRevision: mustInt64(v)}
case pb.Compare_MOD: case pb.Compare_MOD:
cmp.TargetUnion = &pb.Compare_ModRevision{ModRevision: mustInt64(v)} cmp.TargetUnion = &pb.Compare_ModRevision{ModRevision: mustInt64(v)}
case pb.Compare_LEASE:
cmp.TargetUnion = &pb.Compare_Lease{Lease: mustInt64orLeaseID(v)}
default: default:
panic("Unknown compare type") panic("Unknown compare type")
} }
@ -82,6 +84,12 @@ func ModRevision(key string) Cmp {
return Cmp{Key: []byte(key), Target: pb.Compare_MOD} return Cmp{Key: []byte(key), Target: pb.Compare_MOD}
} }
// LeaseValue compares a key's LeaseID to a value of your choosing. The empty
// LeaseID is 0, otherwise known as `NoLease`.
func LeaseValue(key string) Cmp {
return Cmp{Key: []byte(key), Target: pb.Compare_LEASE}
}
// KeyBytes returns the byte slice holding with the comparison key. // KeyBytes returns the byte slice holding with the comparison key.
func (cmp *Cmp) KeyBytes() []byte { return cmp.Key } func (cmp *Cmp) KeyBytes() []byte { return cmp.Key }
@ -111,6 +119,7 @@ func (cmp Cmp) WithPrefix() Cmp {
return cmp return cmp
} }
// mustInt64 panics if val isn't an int or int64. It returns an int64 otherwise.
func mustInt64(val interface{}) int64 { func mustInt64(val interface{}) int64 {
if v, ok := val.(int64); ok { if v, ok := val.(int64); ok {
return v return v
@ -120,3 +129,12 @@ func mustInt64(val interface{}) int64 {
} }
panic("bad value") panic("bad value")
} }
// mustInt64orLeaseID panics if val isn't a LeaseID, int or int64. It returns an
// int64 otherwise.
func mustInt64orLeaseID(val interface{}) int64 {
if v, ok := val.(LeaseID); ok {
return int64(v)
}
return mustInt64(val)
}

View File

@ -15,10 +15,10 @@
package clientv3 package clientv3
import ( import (
"context"
"crypto/tls" "crypto/tls"
"time" "time"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -33,10 +33,31 @@ type Config struct {
// DialTimeout is the timeout for failing to establish a connection. // DialTimeout is the timeout for failing to establish a connection.
DialTimeout time.Duration `json:"dial-timeout"` DialTimeout time.Duration `json:"dial-timeout"`
// DialKeepAliveTime is the time after which client pings the server to see if
// transport is alive.
DialKeepAliveTime time.Duration `json:"dial-keep-alive-time"`
// DialKeepAliveTimeout is the time that the client waits for a response for the
// keep-alive probe. If the response is not received in this time, the connection is closed.
DialKeepAliveTimeout time.Duration `json:"dial-keep-alive-timeout"`
// MaxCallSendMsgSize is the client-side request send limit in bytes.
// If 0, it defaults to 2.0 MiB (2 * 1024 * 1024).
// Make sure that "MaxCallSendMsgSize" < server-side default send/recv limit.
// ("--max-request-bytes" flag to etcd or "embed.Config.MaxRequestBytes").
MaxCallSendMsgSize int
// MaxCallRecvMsgSize is the client-side response receive limit.
// If 0, it defaults to "math.MaxInt32", because range response can
// easily exceed request send limits.
// Make sure that "MaxCallRecvMsgSize" >= server-side default send/recv limit.
// ("--max-request-bytes" flag to etcd or "embed.Config.MaxRequestBytes").
MaxCallRecvMsgSize int
// TLS holds the client secure credentials, if any. // TLS holds the client secure credentials, if any.
TLS *tls.Config TLS *tls.Config
// Username is a username for authentication. // Username is a user name for authentication.
Username string `json:"username"` Username string `json:"username"`
// Password is a password for authentication. // Password is a password for authentication.

View File

@ -16,6 +16,22 @@
// //
// Create client using `clientv3.New`: // Create client using `clientv3.New`:
// //
// // expect dial time-out on ipv4 blackhole
// _, err := clientv3.New(clientv3.Config{
// Endpoints: []string{"http://254.0.0.1:12345"},
// DialTimeout: 2 * time.Second
// })
//
// // etcd clientv3 >= v3.2.10, grpc/grpc-go >= v1.7.3
// if err == context.DeadlineExceeded {
// // handle errors
// }
//
// // etcd clientv3 <= v3.2.9, grpc/grpc-go <= v1.2.1
// if err == grpc.ErrClientConnTimeout {
// // handle errors
// }
//
// cli, err := clientv3.New(clientv3.Config{ // cli, err := clientv3.New(clientv3.Config{
// Endpoints: []string{"localhost:2379", "localhost:22379", "localhost:32379"}, // Endpoints: []string{"localhost:2379", "localhost:22379", "localhost:32379"},
// DialTimeout: 5 * time.Second, // DialTimeout: 5 * time.Second,
@ -28,7 +44,7 @@
// Make sure to close the client after using it. If the client is not closed, the // Make sure to close the client after using it. If the client is not closed, the
// connection will have leaky goroutines. // connection will have leaky goroutines.
// //
// To specify client request timeout, pass context.WithTimeout to APIs: // To specify a client request timeout, wrap the context with context.WithTimeout:
// //
// ctx, cancel := context.WithTimeout(context.Background(), timeout) // ctx, cancel := context.WithTimeout(context.Background(), timeout)
// resp, err := kvc.Put(ctx, "sample_key", "sample_value") // resp, err := kvc.Put(ctx, "sample_key", "sample_value")
@ -41,10 +57,11 @@
// The Client has internal state (watchers and leases), so Clients should be reused instead of created as needed. // The Client has internal state (watchers and leases), so Clients should be reused instead of created as needed.
// Clients are safe for concurrent use by multiple goroutines. // Clients are safe for concurrent use by multiple goroutines.
// //
// etcd client returns 2 types of errors: // etcd client returns 3 types of errors:
// //
// 1. context error: canceled or deadline exceeded. // 1. context error: canceled or deadline exceeded.
// 2. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go // 2. gRPC status error: e.g. when clock drifts in server-side before client's context deadline exceeded.
// 3. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go
// //
// Here is the example code to handle client errors: // Here is the example code to handle client errors:
// //
@ -54,6 +71,12 @@
// // ctx is canceled by another routine // // ctx is canceled by another routine
// } else if err == context.DeadlineExceeded { // } else if err == context.DeadlineExceeded {
// // ctx is attached with a deadline and it exceeded // // ctx is attached with a deadline and it exceeded
// } else if ev, ok := status.FromError(err); ok {
// code := ev.Code()
// if code == codes.DeadlineExceeded {
// // server-side context might have timed-out first (due to clock skew)
// // while original client-side context is not timed-out yet
// }
// } else if verr, ok := err.(*v3rpc.ErrEmptyKey); ok { // } else if verr, ok := err.(*v3rpc.ErrEmptyKey); ok {
// // process (verr.Errors) // // process (verr.Errors)
// } else { // } else {
@ -61,4 +84,14 @@
// } // }
// } // }
// //
// go func() { cli.Close() }()
// _, err := kvc.Get(ctx, "a")
// if err != nil {
// if err == context.Canceled {
// // grpc balancer calls 'Get' with an inflight client.Close
// } else if err == grpc.ErrClientConnClosing {
// // grpc balancer calls 'Get' after client.Close.
// }
// }
//
package clientv3 package clientv3

46
vendor/github.com/coreos/etcd/clientv3/grpc_options.go generated vendored Normal file
View File

@ -0,0 +1,46 @@
// Copyright 2017 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package clientv3
import (
"math"
"google.golang.org/grpc"
)
var (
// Disable gRPC internal retrial logic
// TODO: enable when gRPC retry is stable (FailFast=false)
// Reference:
// - https://github.com/grpc/grpc-go/issues/1532
// - https://github.com/grpc/proposal/blob/master/A6-client-retries.md
defaultFailFast = grpc.FailFast(true)
// client-side request send limit, gRPC default is math.MaxInt32
// Make sure that "client-side send limit < server-side default send/recv limit"
// Same value as "embed.DefaultMaxRequestBytes" plus gRPC overhead bytes
defaultMaxCallSendMsgSize = grpc.MaxCallSendMsgSize(2 * 1024 * 1024)
// client-side response receive limit, gRPC default is 4MB
// Make sure that "client-side receive limit >= server-side default send/recv limit"
// because range response can easily exceed request send limits
// Default to math.MaxInt32; writes exceeding server-side send limit fails anyway
defaultMaxCallRecvMsgSize = grpc.MaxCallRecvMsgSize(math.MaxInt32)
)
// defaultCallOpts defines a list of default "gRPC.CallOption".
// Some options are exposed to "clientv3.Config".
// Defaults will be overridden by the settings in "clientv3.Config".
var defaultCallOpts = []grpc.CallOption{defaultFailFast, defaultMaxCallSendMsgSize, defaultMaxCallRecvMsgSize}

View File

@ -0,0 +1,609 @@
// Copyright 2017 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package clientv3
import (
"context"
"errors"
"net/url"
"strings"
"sync"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/status"
)
const (
minHealthRetryDuration = 3 * time.Second
unknownService = "unknown service grpc.health.v1.Health"
)
// ErrNoAddrAvilable is returned by Get() when the balancer does not have
// any active connection to endpoints at the time.
// This error is returned only when opts.BlockingWait is true.
var ErrNoAddrAvilable = status.Error(codes.Unavailable, "there is no address available")
type healthCheckFunc func(ep string) (bool, error)
type notifyMsg int
const (
notifyReset notifyMsg = iota
notifyNext
)
// healthBalancer does the bare minimum to expose multiple eps
// to the grpc reconnection code path
type healthBalancer struct {
// addrs are the client's endpoint addresses for grpc
addrs []grpc.Address
// eps holds the raw endpoints from the client
eps []string
// notifyCh notifies grpc of the set of addresses for connecting
notifyCh chan []grpc.Address
// readyc closes once the first connection is up
readyc chan struct{}
readyOnce sync.Once
// healthCheck checks an endpoint's health.
healthCheck healthCheckFunc
healthCheckTimeout time.Duration
unhealthyMu sync.RWMutex
unhealthyHostPorts map[string]time.Time
// mu protects all fields below.
mu sync.RWMutex
// upc closes when pinAddr transitions from empty to non-empty or the balancer closes.
upc chan struct{}
// downc closes when grpc calls down() on pinAddr
downc chan struct{}
// stopc is closed to signal updateNotifyLoop should stop.
stopc chan struct{}
stopOnce sync.Once
wg sync.WaitGroup
// donec closes when all goroutines are exited
donec chan struct{}
// updateAddrsC notifies updateNotifyLoop to update addrs.
updateAddrsC chan notifyMsg
// 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.
hostPort2ep map[string]string
// pinAddr is the currently pinned address; set to the empty string on
// initialization and shutdown.
pinAddr string
closed bool
}
func newHealthBalancer(eps []string, timeout time.Duration, hc healthCheckFunc) *healthBalancer {
notifyCh := make(chan []grpc.Address)
addrs := eps2addrs(eps)
hb := &healthBalancer{
addrs: addrs,
eps: eps,
notifyCh: notifyCh,
readyc: make(chan struct{}),
healthCheck: hc,
unhealthyHostPorts: make(map[string]time.Time),
upc: make(chan struct{}),
stopc: make(chan struct{}),
downc: make(chan struct{}),
donec: make(chan struct{}),
updateAddrsC: make(chan notifyMsg),
hostPort2ep: getHostPort2ep(eps),
}
if timeout < minHealthRetryDuration {
timeout = minHealthRetryDuration
}
hb.healthCheckTimeout = timeout
close(hb.downc)
go hb.updateNotifyLoop()
hb.wg.Add(1)
go func() {
defer hb.wg.Done()
hb.updateUnhealthy()
}()
return hb
}
func (b *healthBalancer) Start(target string, config grpc.BalancerConfig) error { return nil }
func (b *healthBalancer) ConnectNotify() <-chan struct{} {
b.mu.Lock()
defer b.mu.Unlock()
return b.upc
}
func (b *healthBalancer) ready() <-chan struct{} { return b.readyc }
func (b *healthBalancer) endpoint(hostPort string) string {
b.mu.RLock()
defer b.mu.RUnlock()
return b.hostPort2ep[hostPort]
}
func (b *healthBalancer) pinned() string {
b.mu.RLock()
defer b.mu.RUnlock()
return b.pinAddr
}
func (b *healthBalancer) hostPortError(hostPort string, err error) {
if b.endpoint(hostPort) == "" {
logger.Lvl(4).Infof("clientv3/balancer: %q is stale (skip marking as unhealthy on %q)", hostPort, err.Error())
return
}
b.unhealthyMu.Lock()
b.unhealthyHostPorts[hostPort] = time.Now()
b.unhealthyMu.Unlock()
logger.Lvl(4).Infof("clientv3/balancer: %q is marked unhealthy (%q)", hostPort, err.Error())
}
func (b *healthBalancer) removeUnhealthy(hostPort, msg string) {
if b.endpoint(hostPort) == "" {
logger.Lvl(4).Infof("clientv3/balancer: %q was not in unhealthy (%q)", hostPort, msg)
return
}
b.unhealthyMu.Lock()
delete(b.unhealthyHostPorts, hostPort)
b.unhealthyMu.Unlock()
logger.Lvl(4).Infof("clientv3/balancer: %q is removed from unhealthy (%q)", hostPort, msg)
}
func (b *healthBalancer) countUnhealthy() (count int) {
b.unhealthyMu.RLock()
count = len(b.unhealthyHostPorts)
b.unhealthyMu.RUnlock()
return count
}
func (b *healthBalancer) isUnhealthy(hostPort string) (unhealthy bool) {
b.unhealthyMu.RLock()
_, unhealthy = b.unhealthyHostPorts[hostPort]
b.unhealthyMu.RUnlock()
return unhealthy
}
func (b *healthBalancer) cleanupUnhealthy() {
b.unhealthyMu.Lock()
for k, v := range b.unhealthyHostPorts {
if time.Since(v) > b.healthCheckTimeout {
delete(b.unhealthyHostPorts, k)
logger.Lvl(4).Infof("clientv3/balancer: removed %q from unhealthy after %v", k, b.healthCheckTimeout)
}
}
b.unhealthyMu.Unlock()
}
func (b *healthBalancer) liveAddrs() ([]grpc.Address, map[string]struct{}) {
unhealthyCnt := b.countUnhealthy()
b.mu.RLock()
defer b.mu.RUnlock()
hbAddrs := b.addrs
if len(b.addrs) == 1 || unhealthyCnt == 0 || unhealthyCnt == len(b.addrs) {
liveHostPorts := make(map[string]struct{}, len(b.hostPort2ep))
for k := range b.hostPort2ep {
liveHostPorts[k] = struct{}{}
}
return hbAddrs, liveHostPorts
}
addrs := make([]grpc.Address, 0, len(b.addrs)-unhealthyCnt)
liveHostPorts := make(map[string]struct{}, len(addrs))
for _, addr := range b.addrs {
if !b.isUnhealthy(addr.Addr) {
addrs = append(addrs, addr)
liveHostPorts[addr.Addr] = struct{}{}
}
}
return addrs, liveHostPorts
}
func (b *healthBalancer) updateUnhealthy() {
for {
select {
case <-time.After(b.healthCheckTimeout):
b.cleanupUnhealthy()
pinned := b.pinned()
if pinned == "" || b.isUnhealthy(pinned) {
select {
case b.updateAddrsC <- notifyNext:
case <-b.stopc:
return
}
}
case <-b.stopc:
return
}
}
}
func (b *healthBalancer) updateAddrs(eps ...string) {
np := getHostPort2ep(eps)
b.mu.Lock()
defer b.mu.Unlock()
match := len(np) == len(b.hostPort2ep)
if match {
for k, v := range np {
if b.hostPort2ep[k] != v {
match = false
break
}
}
}
if match {
// same endpoints, so no need to update address
return
}
b.hostPort2ep = np
b.addrs, b.eps = eps2addrs(eps), eps
b.unhealthyMu.Lock()
b.unhealthyHostPorts = make(map[string]time.Time)
b.unhealthyMu.Unlock()
}
func (b *healthBalancer) next() {
b.mu.RLock()
downc := b.downc
b.mu.RUnlock()
select {
case b.updateAddrsC <- notifyNext:
case <-b.stopc:
}
// wait until disconnect so new RPCs are not issued on old connection
select {
case <-downc:
case <-b.stopc:
}
}
func (b *healthBalancer) updateNotifyLoop() {
defer close(b.donec)
for {
b.mu.RLock()
upc, downc, addr := b.upc, b.downc, b.pinAddr
b.mu.RUnlock()
// downc or upc should be closed
select {
case <-downc:
downc = nil
default:
}
select {
case <-upc:
upc = nil
default:
}
switch {
case downc == nil && upc == nil:
// stale
select {
case <-b.stopc:
return
default:
}
case downc == nil:
b.notifyAddrs(notifyReset)
select {
case <-upc:
case msg := <-b.updateAddrsC:
b.notifyAddrs(msg)
case <-b.stopc:
return
}
case upc == nil:
select {
// close connections that are not the pinned address
case b.notifyCh <- []grpc.Address{{Addr: addr}}:
case <-downc:
case <-b.stopc:
return
}
select {
case <-downc:
b.notifyAddrs(notifyReset)
case msg := <-b.updateAddrsC:
b.notifyAddrs(msg)
case <-b.stopc:
return
}
}
}
}
func (b *healthBalancer) notifyAddrs(msg notifyMsg) {
if msg == notifyNext {
select {
case b.notifyCh <- []grpc.Address{}:
case <-b.stopc:
return
}
}
b.mu.RLock()
pinAddr := b.pinAddr
downc := b.downc
b.mu.RUnlock()
addrs, hostPorts := b.liveAddrs()
var waitDown bool
if pinAddr != "" {
_, ok := hostPorts[pinAddr]
waitDown = !ok
}
select {
case b.notifyCh <- addrs:
if waitDown {
select {
case <-downc:
case <-b.stopc:
}
}
case <-b.stopc:
}
}
func (b *healthBalancer) Up(addr grpc.Address) func(error) {
if !b.mayPin(addr) {
return func(err error) {}
}
b.mu.Lock()
defer b.mu.Unlock()
// gRPC might call Up after it called Close. We add this check
// to "fix" it up at application layer. Otherwise, will panic
// if b.upc is already closed.
if b.closed {
return func(err error) {}
}
// gRPC might call Up on a stale address.
// Prevent updating pinAddr with a stale address.
if !hasAddr(b.addrs, addr.Addr) {
return func(err error) {}
}
if b.pinAddr != "" {
logger.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (already pinned %q)", addr.Addr, b.pinAddr)
return func(err error) {}
}
// notify waiting Get()s and pin first connected address
close(b.upc)
b.downc = make(chan struct{})
b.pinAddr = addr.Addr
logger.Lvl(4).Infof("clientv3/balancer: pin %q", addr.Addr)
// notify client that a connection is up
b.readyOnce.Do(func() { close(b.readyc) })
return func(err error) {
// If connected to a black hole endpoint or a killed server, the gRPC ping
// timeout will induce a network I/O error, and retrying until success;
// finding healthy endpoint on retry could take several timeouts and redials.
// To avoid wasting retries, gray-list unhealthy endpoints.
b.hostPortError(addr.Addr, err)
b.mu.Lock()
b.upc = make(chan struct{})
close(b.downc)
b.pinAddr = ""
b.mu.Unlock()
logger.Lvl(4).Infof("clientv3/balancer: unpin %q (%q)", addr.Addr, err.Error())
}
}
func (b *healthBalancer) mayPin(addr grpc.Address) bool {
if b.endpoint(addr.Addr) == "" { // stale host:port
return false
}
b.unhealthyMu.RLock()
unhealthyCnt := len(b.unhealthyHostPorts)
failedTime, bad := b.unhealthyHostPorts[addr.Addr]
b.unhealthyMu.RUnlock()
b.mu.RLock()
skip := len(b.addrs) == 1 || unhealthyCnt == 0 || len(b.addrs) == unhealthyCnt
b.mu.RUnlock()
if skip || !bad {
return true
}
// prevent isolated member's endpoint from being infinitely retried, as follows:
// 1. keepalive pings detects GoAway with http2.ErrCodeEnhanceYourCalm
// 2. balancer 'Up' unpins with grpc: failed with network I/O error
// 3. grpc-healthcheck still SERVING, thus retry to pin
// instead, return before grpc-healthcheck if failed within healthcheck timeout
if elapsed := time.Since(failedTime); elapsed < b.healthCheckTimeout {
logger.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (failed %v ago, require minimum %v after failure)", addr.Addr, elapsed, b.healthCheckTimeout)
return false
}
if ok, _ := b.healthCheck(addr.Addr); ok {
b.removeUnhealthy(addr.Addr, "health check success")
return true
}
b.hostPortError(addr.Addr, errors.New("health check failed"))
return false
}
func (b *healthBalancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (grpc.Address, func(), error) {
var (
addr string
closed bool
)
// If opts.BlockingWait is false (for fail-fast RPCs), it should return
// an address it has notified via Notify immediately instead of blocking.
if !opts.BlockingWait {
b.mu.RLock()
closed = b.closed
addr = b.pinAddr
b.mu.RUnlock()
if closed {
return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
}
if addr == "" {
return grpc.Address{Addr: ""}, nil, ErrNoAddrAvilable
}
return grpc.Address{Addr: addr}, func() {}, nil
}
for {
b.mu.RLock()
ch := b.upc
b.mu.RUnlock()
select {
case <-ch:
case <-b.donec:
return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
case <-ctx.Done():
return grpc.Address{Addr: ""}, nil, ctx.Err()
}
b.mu.RLock()
closed = b.closed
addr = b.pinAddr
b.mu.RUnlock()
// Close() which sets b.closed = true can be called before Get(), Get() must exit if balancer is closed.
if closed {
return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
}
if addr != "" {
break
}
}
return grpc.Address{Addr: addr}, func() {}, nil
}
func (b *healthBalancer) Notify() <-chan []grpc.Address { return b.notifyCh }
func (b *healthBalancer) Close() error {
b.mu.Lock()
// In case gRPC calls close twice. TODO: remove the checking
// when we are sure that gRPC wont call close twice.
if b.closed {
b.mu.Unlock()
<-b.donec
return nil
}
b.closed = true
b.stopOnce.Do(func() { close(b.stopc) })
b.pinAddr = ""
// In the case of following scenario:
// 1. upc is not closed; no pinned address
// 2. client issues an RPC, calling invoke(), which calls Get(), enters for loop, blocks
// 3. client.conn.Close() calls balancer.Close(); closed = true
// 4. for loop in Get() never exits since ctx is the context passed in by the client and may not be canceled
// we must close upc so Get() exits from blocking on upc
select {
case <-b.upc:
default:
// terminate all waiting Get()s
close(b.upc)
}
b.mu.Unlock()
b.wg.Wait()
// wait for updateNotifyLoop to finish
<-b.donec
close(b.notifyCh)
return nil
}
func grpcHealthCheck(client *Client, ep string) (bool, error) {
conn, err := client.dial(ep)
if err != nil {
return false, err
}
defer conn.Close()
cli := healthpb.NewHealthClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
resp, err := cli.Check(ctx, &healthpb.HealthCheckRequest{})
cancel()
if err != nil {
if s, ok := status.FromError(err); ok && s.Code() == codes.Unavailable {
if s.Message() == unknownService { // etcd < v3.3.0
return true, nil
}
}
return false, err
}
return resp.Status == healthpb.HealthCheckResponse_SERVING, nil
}
func hasAddr(addrs []grpc.Address, targetAddr string) bool {
for _, addr := range addrs {
if targetAddr == addr.Addr {
return true
}
}
return false
}
func getHost(ep string) string {
url, uerr := url.Parse(ep)
if uerr != nil || !strings.Contains(ep, "://") {
return ep
}
return url.Host
}
func eps2addrs(eps []string) []grpc.Address {
addrs := make([]grpc.Address, len(eps))
for i := range eps {
addrs[i].Addr = getHost(eps[i])
}
return addrs
}
func getHostPort2ep(eps []string) map[string]string {
hm := make(map[string]string, len(eps))
for i := range eps {
_, host, _ := parseEndpoint(eps[i])
hm[host] = eps[i]
}
return hm
}

View File

@ -15,8 +15,10 @@
package clientv3 package clientv3
import ( import (
"context"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -74,16 +76,38 @@ func (op OpResponse) Get() *GetResponse { return op.get }
func (op OpResponse) Del() *DeleteResponse { return op.del } func (op OpResponse) Del() *DeleteResponse { return op.del }
func (op OpResponse) Txn() *TxnResponse { return op.txn } func (op OpResponse) Txn() *TxnResponse { return op.txn }
func (resp *PutResponse) OpResponse() OpResponse {
return OpResponse{put: resp}
}
func (resp *GetResponse) OpResponse() OpResponse {
return OpResponse{get: resp}
}
func (resp *DeleteResponse) OpResponse() OpResponse {
return OpResponse{del: resp}
}
func (resp *TxnResponse) OpResponse() OpResponse {
return OpResponse{txn: resp}
}
type kv struct { type kv struct {
remote pb.KVClient remote pb.KVClient
callOpts []grpc.CallOption
} }
func NewKV(c *Client) KV { func NewKV(c *Client) KV {
return &kv{remote: RetryKVClient(c)} api := &kv{remote: RetryKVClient(c)}
if c != nil {
api.callOpts = c.callOpts
}
return api
} }
func NewKVFromKVClient(remote pb.KVClient) KV { func NewKVFromKVClient(remote pb.KVClient, c *Client) KV {
return &kv{remote: remote} api := &kv{remote: remote}
if c != nil {
api.callOpts = c.callOpts
}
return api
} }
func (kv *kv) Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) { func (kv *kv) Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) {
@ -102,7 +126,7 @@ func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption) (*Delete
} }
func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) { func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) {
resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest()) resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest(), kv.callOpts...)
if err != nil { if err != nil {
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
@ -111,59 +135,43 @@ func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*C
func (kv *kv) Txn(ctx context.Context) Txn { func (kv *kv) Txn(ctx context.Context) Txn {
return &txn{ return &txn{
kv: kv, kv: kv,
ctx: ctx, ctx: ctx,
callOpts: kv.callOpts,
} }
} }
func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) { func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) {
for {
resp, err := kv.do(ctx, op)
if err == nil {
return resp, nil
}
if isHaltErr(ctx, err) {
return resp, toErr(ctx, err)
}
// do not retry on modifications
if op.isWrite() {
return resp, toErr(ctx, err)
}
}
}
func (kv *kv) do(ctx context.Context, op Op) (OpResponse, error) {
var err error var err error
switch op.t { switch op.t {
case tRange: case tRange:
var resp *pb.RangeResponse var resp *pb.RangeResponse
resp, err = kv.remote.Range(ctx, op.toRangeRequest(), grpc.FailFast(false)) resp, err = kv.remote.Range(ctx, op.toRangeRequest(), kv.callOpts...)
if err == nil { if err == nil {
return OpResponse{get: (*GetResponse)(resp)}, nil return OpResponse{get: (*GetResponse)(resp)}, nil
} }
case tPut: case tPut:
var resp *pb.PutResponse var resp *pb.PutResponse
r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue, IgnoreLease: op.ignoreLease} r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue, IgnoreLease: op.ignoreLease}
resp, err = kv.remote.Put(ctx, r) resp, err = kv.remote.Put(ctx, r, kv.callOpts...)
if err == nil { if err == nil {
return OpResponse{put: (*PutResponse)(resp)}, nil return OpResponse{put: (*PutResponse)(resp)}, nil
} }
case tDeleteRange: case tDeleteRange:
var resp *pb.DeleteRangeResponse var resp *pb.DeleteRangeResponse
r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV} r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV}
resp, err = kv.remote.DeleteRange(ctx, r) resp, err = kv.remote.DeleteRange(ctx, r, kv.callOpts...)
if err == nil { if err == nil {
return OpResponse{del: (*DeleteResponse)(resp)}, nil return OpResponse{del: (*DeleteResponse)(resp)}, nil
} }
case tTxn: case tTxn:
var resp *pb.TxnResponse var resp *pb.TxnResponse
resp, err = kv.remote.Txn(ctx, op.toTxnRequest()) resp, err = kv.remote.Txn(ctx, op.toTxnRequest(), kv.callOpts...)
if err == nil { if err == nil {
return OpResponse{txn: (*TxnResponse)(resp)}, nil return OpResponse{txn: (*TxnResponse)(resp)}, nil
} }
default: default:
panic("Unknown op") panic("Unknown op")
} }
return OpResponse{}, err return OpResponse{}, toErr(ctx, err)
} }

View File

@ -15,12 +15,13 @@
package clientv3 package clientv3
import ( import (
"context"
"sync" "sync"
"time" "time"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
) )
@ -30,7 +31,7 @@ type (
LeaseID int64 LeaseID int64
) )
// LeaseGrantResponse is used to convert the protobuf grant response. // LeaseGrantResponse wraps the protobuf message LeaseGrantResponse.
type LeaseGrantResponse struct { type LeaseGrantResponse struct {
*pb.ResponseHeader *pb.ResponseHeader
ID LeaseID ID LeaseID
@ -38,19 +39,19 @@ type LeaseGrantResponse struct {
Error string Error string
} }
// LeaseKeepAliveResponse is used to convert the protobuf keepalive response. // LeaseKeepAliveResponse wraps the protobuf message LeaseKeepAliveResponse.
type LeaseKeepAliveResponse struct { type LeaseKeepAliveResponse struct {
*pb.ResponseHeader *pb.ResponseHeader
ID LeaseID ID LeaseID
TTL int64 TTL int64
} }
// LeaseTimeToLiveResponse is used to convert the protobuf lease timetolive response. // LeaseTimeToLiveResponse wraps the protobuf message LeaseTimeToLiveResponse.
type LeaseTimeToLiveResponse struct { type LeaseTimeToLiveResponse struct {
*pb.ResponseHeader *pb.ResponseHeader
ID LeaseID `json:"id"` ID LeaseID `json:"id"`
// TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds. // TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds. Expired lease will return -1.
TTL int64 `json:"ttl"` TTL int64 `json:"ttl"`
// GrantedTTL is the initial granted time in seconds upon lease creation/renewal. // GrantedTTL is the initial granted time in seconds upon lease creation/renewal.
@ -60,6 +61,18 @@ type LeaseTimeToLiveResponse struct {
Keys [][]byte `json:"keys"` Keys [][]byte `json:"keys"`
} }
// LeaseStatus represents a lease status.
type LeaseStatus struct {
ID LeaseID `json:"id"`
// TODO: TTL int64
}
// LeaseLeasesResponse wraps the protobuf message LeaseLeasesResponse.
type LeaseLeasesResponse struct {
*pb.ResponseHeader
Leases []LeaseStatus `json:"leases"`
}
const ( const (
// defaultTTL is the assumed lease TTL used for the first keepalive // defaultTTL is the assumed lease TTL used for the first keepalive
// deadline before the actual TTL is known to the client. // deadline before the actual TTL is known to the client.
@ -98,11 +111,32 @@ type Lease interface {
// TimeToLive retrieves the lease information of the given lease ID. // TimeToLive retrieves the lease information of the given lease ID.
TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error) TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error)
// KeepAlive keeps the given lease alive forever. // Leases retrieves all leases.
Leases(ctx context.Context) (*LeaseLeasesResponse, error)
// KeepAlive keeps the given lease alive forever. If the keepalive response
// posted to the channel is not consumed immediately, the lease client will
// continue sending keep alive requests to the etcd server at least every
// second until latest response is consumed.
//
// The returned "LeaseKeepAliveResponse" channel closes if underlying keep
// alive stream is interrupted in some way the client cannot handle itself;
// given context "ctx" is canceled or timed out. "LeaseKeepAliveResponse"
// from this closed channel is nil.
//
// If client keep alive loop halts with an unexpected error (e.g. "etcdserver:
// no leader") or canceled by the caller (e.g. context.Canceled), the error
// is returned. Otherwise, it retries.
//
// TODO(v4.0): post errors to last keep alive message before closing
// (see https://github.com/coreos/etcd/pull/7866)
KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error)
// KeepAliveOnce renews the lease once. In most of the cases, Keepalive // KeepAliveOnce renews the lease once. The response corresponds to the
// should be used instead of KeepAliveOnce. // first message from calling KeepAlive. If the response has a recoverable
// error, KeepAliveOnce will retry the RPC with a new keep alive message.
//
// In most of the cases, Keepalive should be used instead of KeepAliveOnce.
KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error)
// Close releases all resources Lease keeps for efficient communication // Close releases all resources Lease keeps for efficient communication
@ -133,6 +167,8 @@ type lessor struct {
// firstKeepAliveOnce ensures stream starts after first KeepAlive call. // firstKeepAliveOnce ensures stream starts after first KeepAlive call.
firstKeepAliveOnce sync.Once firstKeepAliveOnce sync.Once
callOpts []grpc.CallOption
} }
// keepAlive multiplexes a keepalive for a lease over multiple channels // keepAlive multiplexes a keepalive for a lease over multiple channels
@ -148,10 +184,10 @@ type keepAlive struct {
} }
func NewLease(c *Client) Lease { func NewLease(c *Client) Lease {
return NewLeaseFromLeaseClient(RetryLeaseClient(c), c.cfg.DialTimeout+time.Second) return NewLeaseFromLeaseClient(RetryLeaseClient(c), c, c.cfg.DialTimeout+time.Second)
} }
func NewLeaseFromLeaseClient(remote pb.LeaseClient, keepAliveTimeout time.Duration) Lease { func NewLeaseFromLeaseClient(remote pb.LeaseClient, c *Client, keepAliveTimeout time.Duration) Lease {
l := &lessor{ l := &lessor{
donec: make(chan struct{}), donec: make(chan struct{}),
keepAlives: make(map[LeaseID]*keepAlive), keepAlives: make(map[LeaseID]*keepAlive),
@ -161,62 +197,64 @@ func NewLeaseFromLeaseClient(remote pb.LeaseClient, keepAliveTimeout time.Durati
if l.firstKeepAliveTimeout == time.Second { if l.firstKeepAliveTimeout == time.Second {
l.firstKeepAliveTimeout = defaultTTL l.firstKeepAliveTimeout = defaultTTL
} }
if c != nil {
l.callOpts = c.callOpts
}
reqLeaderCtx := WithRequireLeader(context.Background()) reqLeaderCtx := WithRequireLeader(context.Background())
l.stopCtx, l.stopCancel = context.WithCancel(reqLeaderCtx) l.stopCtx, l.stopCancel = context.WithCancel(reqLeaderCtx)
return l return l
} }
func (l *lessor) Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error) { func (l *lessor) Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error) {
for { r := &pb.LeaseGrantRequest{TTL: ttl}
r := &pb.LeaseGrantRequest{TTL: ttl} resp, err := l.remote.LeaseGrant(ctx, r, l.callOpts...)
resp, err := l.remote.LeaseGrant(ctx, r) if err == nil {
if err == nil { gresp := &LeaseGrantResponse{
gresp := &LeaseGrantResponse{ ResponseHeader: resp.GetHeader(),
ResponseHeader: resp.GetHeader(), ID: LeaseID(resp.ID),
ID: LeaseID(resp.ID), TTL: resp.TTL,
TTL: resp.TTL, Error: resp.Error,
Error: resp.Error,
}
return gresp, nil
}
if isHaltErr(ctx, err) {
return nil, toErr(ctx, err)
} }
return gresp, nil
} }
return nil, toErr(ctx, err)
} }
func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) { func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) {
for { r := &pb.LeaseRevokeRequest{ID: int64(id)}
r := &pb.LeaseRevokeRequest{ID: int64(id)} resp, err := l.remote.LeaseRevoke(ctx, r, l.callOpts...)
resp, err := l.remote.LeaseRevoke(ctx, r) if err == nil {
return (*LeaseRevokeResponse)(resp), nil
if err == nil {
return (*LeaseRevokeResponse)(resp), nil
}
if isHaltErr(ctx, err) {
return nil, toErr(ctx, err)
}
} }
return nil, toErr(ctx, err)
} }
func (l *lessor) TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error) { func (l *lessor) TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error) {
for { r := toLeaseTimeToLiveRequest(id, opts...)
r := toLeaseTimeToLiveRequest(id, opts...) resp, err := l.remote.LeaseTimeToLive(ctx, r, l.callOpts...)
resp, err := l.remote.LeaseTimeToLive(ctx, r, grpc.FailFast(false)) if err == nil {
if err == nil { gresp := &LeaseTimeToLiveResponse{
gresp := &LeaseTimeToLiveResponse{ ResponseHeader: resp.GetHeader(),
ResponseHeader: resp.GetHeader(), ID: LeaseID(resp.ID),
ID: LeaseID(resp.ID), TTL: resp.TTL,
TTL: resp.TTL, GrantedTTL: resp.GrantedTTL,
GrantedTTL: resp.GrantedTTL, Keys: resp.Keys,
Keys: resp.Keys,
}
return gresp, nil
}
if isHaltErr(ctx, err) {
return nil, toErr(ctx, err)
} }
return gresp, nil
} }
return nil, toErr(ctx, err)
}
func (l *lessor) Leases(ctx context.Context) (*LeaseLeasesResponse, error) {
resp, err := l.remote.LeaseLeases(ctx, &pb.LeaseLeasesRequest{}, l.callOpts...)
if err == nil {
leases := make([]LeaseStatus, len(resp.Leases))
for i := range resp.Leases {
leases[i] = LeaseStatus{ID: LeaseID(resp.Leases[i].ID)}
}
return &LeaseLeasesResponse{ResponseHeader: resp.GetHeader(), Leases: leases}, nil
}
return nil, toErr(ctx, err)
} }
func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) { func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) {
@ -314,7 +352,7 @@ func (l *lessor) keepAliveCtxCloser(id LeaseID, ctx context.Context, donec <-cha
} }
} }
// closeRequireLeader scans all keep alives for ctxs that have require leader // closeRequireLeader scans keepAlives for ctxs that have require leader
// and closes the associated channels. // and closes the associated channels.
func (l *lessor) closeRequireLeader() { func (l *lessor) closeRequireLeader() {
l.mu.Lock() l.mu.Lock()
@ -357,7 +395,7 @@ func (l *lessor) keepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAlive
cctx, cancel := context.WithCancel(ctx) cctx, cancel := context.WithCancel(ctx)
defer cancel() defer cancel()
stream, err := l.remote.LeaseKeepAlive(cctx, grpc.FailFast(false)) stream, err := l.remote.LeaseKeepAlive(cctx, l.callOpts...)
if err != nil { if err != nil {
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
@ -401,7 +439,6 @@ func (l *lessor) recvKeepAliveLoop() (gerr error) {
} else { } else {
for { for {
resp, err := stream.Recv() resp, err := stream.Recv()
if err != nil { if err != nil {
if canceledByCaller(l.stopCtx, err) { if canceledByCaller(l.stopCtx, err) {
return err return err
@ -426,10 +463,10 @@ func (l *lessor) recvKeepAliveLoop() (gerr error) {
} }
} }
// resetRecv opens a new lease stream and starts sending LeaseKeepAliveRequests // resetRecv opens a new lease stream and starts sending keep alive requests.
func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) { func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) {
sctx, cancel := context.WithCancel(l.stopCtx) sctx, cancel := context.WithCancel(l.stopCtx)
stream, err := l.remote.LeaseKeepAlive(sctx, grpc.FailFast(false)) stream, err := l.remote.LeaseKeepAlive(sctx, l.callOpts...)
if err != nil { if err != nil {
cancel() cancel()
return nil, err return nil, err
@ -505,7 +542,7 @@ func (l *lessor) deadlineLoop() {
} }
} }
// sendKeepAliveLoop sends LeaseKeepAliveRequests for the lifetime of a lease stream // sendKeepAliveLoop sends keep alive requests for the lifetime of the given stream.
func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) { func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) {
for { for {
var tosend []LeaseID var tosend []LeaseID

View File

@ -16,67 +16,120 @@ package clientv3
import ( import (
"io/ioutil" "io/ioutil"
"log"
"sync" "sync"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
) )
// Logger is the logger used by client library. // Logger is the logger used by client library.
// It implements grpclog.Logger interface. // It implements grpclog.LoggerV2 interface.
type Logger grpclog.Logger type Logger interface {
grpclog.LoggerV2
// Lvl returns logger if logger's verbosity level >= "lvl".
// Otherwise, logger that discards all logs.
Lvl(lvl int) Logger
// to satisfy capnslog
Print(args ...interface{})
Printf(format string, args ...interface{})
Println(args ...interface{})
}
var ( var (
logger settableLogger loggerMu sync.RWMutex
logger Logger
) )
type settableLogger struct { type settableLogger struct {
l grpclog.Logger l grpclog.LoggerV2
mu sync.RWMutex mu sync.RWMutex
} }
func init() { func init() {
// disable client side logs by default // disable client side logs by default
logger.mu.Lock() logger = &settableLogger{}
logger.l = log.New(ioutil.Discard, "", 0) SetLogger(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard))
// logger has to override the grpclog at initialization so that
// any changes to the grpclog go through logger with locking
// instead of through SetLogger
//
// now updates only happen through settableLogger.set
grpclog.SetLogger(&logger)
logger.mu.Unlock()
} }
// SetLogger sets client-side Logger. By default, logs are disabled. // SetLogger sets client-side Logger.
func SetLogger(l Logger) { func SetLogger(l grpclog.LoggerV2) {
logger.set(l) loggerMu.Lock()
logger = NewLogger(l)
// override grpclog so that any changes happen with locking
grpclog.SetLoggerV2(logger)
loggerMu.Unlock()
} }
// GetLogger returns the current logger. // GetLogger returns the current logger.
func GetLogger() Logger { func GetLogger() Logger {
return logger.get() loggerMu.RLock()
l := logger
loggerMu.RUnlock()
return l
} }
func (s *settableLogger) set(l Logger) { // NewLogger returns a new Logger with grpclog.LoggerV2.
s.mu.Lock() func NewLogger(gl grpclog.LoggerV2) Logger {
logger.l = l return &settableLogger{l: gl}
s.mu.Unlock()
} }
func (s *settableLogger) get() Logger { func (s *settableLogger) get() grpclog.LoggerV2 {
s.mu.RLock() s.mu.RLock()
l := logger.l l := s.l
s.mu.RUnlock() s.mu.RUnlock()
return l return l
} }
// implement the grpclog.Logger interface // implement the grpclog.LoggerV2 interface
func (s *settableLogger) Info(args ...interface{}) { s.get().Info(args...) }
func (s *settableLogger) Infof(format string, args ...interface{}) { s.get().Infof(format, args...) }
func (s *settableLogger) Infoln(args ...interface{}) { s.get().Infoln(args...) }
func (s *settableLogger) Warning(args ...interface{}) { s.get().Warning(args...) }
func (s *settableLogger) Warningf(format string, args ...interface{}) {
s.get().Warningf(format, args...)
}
func (s *settableLogger) Warningln(args ...interface{}) { s.get().Warningln(args...) }
func (s *settableLogger) Error(args ...interface{}) { s.get().Error(args...) }
func (s *settableLogger) Errorf(format string, args ...interface{}) {
s.get().Errorf(format, args...)
}
func (s *settableLogger) Errorln(args ...interface{}) { s.get().Errorln(args...) }
func (s *settableLogger) Fatal(args ...interface{}) { s.get().Fatal(args...) } func (s *settableLogger) Fatal(args ...interface{}) { s.get().Fatal(args...) }
func (s *settableLogger) Fatalf(format string, args ...interface{}) { s.get().Fatalf(format, args...) } func (s *settableLogger) Fatalf(format string, args ...interface{}) { s.get().Fatalf(format, args...) }
func (s *settableLogger) Fatalln(args ...interface{}) { s.get().Fatalln(args...) } func (s *settableLogger) Fatalln(args ...interface{}) { s.get().Fatalln(args...) }
func (s *settableLogger) Print(args ...interface{}) { s.get().Print(args...) } func (s *settableLogger) Print(args ...interface{}) { s.get().Info(args...) }
func (s *settableLogger) Printf(format string, args ...interface{}) { s.get().Printf(format, args...) } func (s *settableLogger) Printf(format string, args ...interface{}) { s.get().Infof(format, args...) }
func (s *settableLogger) Println(args ...interface{}) { s.get().Println(args...) } func (s *settableLogger) Println(args ...interface{}) { s.get().Infoln(args...) }
func (s *settableLogger) V(l int) bool { return s.get().V(l) }
func (s *settableLogger) Lvl(lvl int) Logger {
s.mu.RLock()
l := s.l
s.mu.RUnlock()
if l.V(lvl) {
return s
}
return &noLogger{}
}
type noLogger struct{}
func (*noLogger) Info(args ...interface{}) {}
func (*noLogger) Infof(format string, args ...interface{}) {}
func (*noLogger) Infoln(args ...interface{}) {}
func (*noLogger) Warning(args ...interface{}) {}
func (*noLogger) Warningf(format string, args ...interface{}) {}
func (*noLogger) Warningln(args ...interface{}) {}
func (*noLogger) Error(args ...interface{}) {}
func (*noLogger) Errorf(format string, args ...interface{}) {}
func (*noLogger) Errorln(args ...interface{}) {}
func (*noLogger) Fatal(args ...interface{}) {}
func (*noLogger) Fatalf(format string, args ...interface{}) {}
func (*noLogger) Fatalln(args ...interface{}) {}
func (*noLogger) Print(args ...interface{}) {}
func (*noLogger) Printf(format string, args ...interface{}) {}
func (*noLogger) Println(args ...interface{}) {}
func (*noLogger) V(l int) bool { return false }
func (ng *noLogger) Lvl(lvl int) Logger { return ng }

View File

@ -15,11 +15,11 @@
package clientv3 package clientv3
import ( import (
"context"
"io" "io"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -28,6 +28,8 @@ type (
AlarmResponse pb.AlarmResponse AlarmResponse pb.AlarmResponse
AlarmMember pb.AlarmMember AlarmMember pb.AlarmMember
StatusResponse pb.StatusResponse StatusResponse pb.StatusResponse
HashKVResponse pb.HashKVResponse
MoveLeaderResponse pb.MoveLeaderResponse
) )
type Maintenance interface { type Maintenance interface {
@ -37,7 +39,7 @@ type Maintenance interface {
// AlarmDisarm disarms a given alarm. // AlarmDisarm disarms a given alarm.
AlarmDisarm(ctx context.Context, m *AlarmMember) (*AlarmResponse, error) AlarmDisarm(ctx context.Context, m *AlarmMember) (*AlarmResponse, error)
// Defragment defragments storage backend of the etcd member with given endpoint. // Defragment releases wasted space from internal fragmentation on a given etcd member.
// Defragment is only needed when deleting a large number of keys and want to reclaim // Defragment is only needed when deleting a large number of keys and want to reclaim
// the resources. // the resources.
// Defragment is an expensive operation. User should avoid defragmenting multiple members // Defragment is an expensive operation. User should avoid defragmenting multiple members
@ -49,36 +51,54 @@ type Maintenance interface {
// Status gets the status of the endpoint. // Status gets the status of the endpoint.
Status(ctx context.Context, endpoint string) (*StatusResponse, error) Status(ctx context.Context, endpoint string) (*StatusResponse, error)
// Snapshot provides a reader for a snapshot of a backend. // HashKV returns a hash of the KV state at the time of the RPC.
// If revision is zero, the hash is computed on all keys. If the revision
// is non-zero, the hash is computed on all keys at or below the given revision.
HashKV(ctx context.Context, endpoint string, rev int64) (*HashKVResponse, error)
// Snapshot provides a reader for a point-in-time snapshot of etcd.
Snapshot(ctx context.Context) (io.ReadCloser, error) Snapshot(ctx context.Context) (io.ReadCloser, error)
// MoveLeader requests current leader to transfer its leadership to the transferee.
// Request must be made to the leader.
MoveLeader(ctx context.Context, transfereeID uint64) (*MoveLeaderResponse, error)
} }
type maintenance struct { type maintenance struct {
dial func(endpoint string) (pb.MaintenanceClient, func(), error) dial func(endpoint string) (pb.MaintenanceClient, func(), error)
remote pb.MaintenanceClient remote pb.MaintenanceClient
callOpts []grpc.CallOption
} }
func NewMaintenance(c *Client) Maintenance { func NewMaintenance(c *Client) Maintenance {
return &maintenance{ api := &maintenance{
dial: func(endpoint string) (pb.MaintenanceClient, func(), error) { dial: func(endpoint string) (pb.MaintenanceClient, func(), error) {
conn, err := c.dial(endpoint) conn, err := c.dial(endpoint)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
cancel := func() { conn.Close() } cancel := func() { conn.Close() }
return pb.NewMaintenanceClient(conn), cancel, nil return RetryMaintenanceClient(c, conn), cancel, nil
}, },
remote: pb.NewMaintenanceClient(c.conn), remote: RetryMaintenanceClient(c, c.conn),
} }
if c != nil {
api.callOpts = c.callOpts
}
return api
} }
func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient) Maintenance { func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient, c *Client) Maintenance {
return &maintenance{ api := &maintenance{
dial: func(string) (pb.MaintenanceClient, func(), error) { dial: func(string) (pb.MaintenanceClient, func(), error) {
return remote, func() {}, nil return remote, func() {}, nil
}, },
remote: remote, remote: remote,
} }
if c != nil {
api.callOpts = c.callOpts
}
return api
} }
func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) { func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) {
@ -87,15 +107,11 @@ func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) {
MemberID: 0, // all MemberID: 0, // all
Alarm: pb.AlarmType_NONE, // all Alarm: pb.AlarmType_NONE, // all
} }
for { resp, err := m.remote.Alarm(ctx, req, m.callOpts...)
resp, err := m.remote.Alarm(ctx, req, grpc.FailFast(false)) if err == nil {
if err == nil { return (*AlarmResponse)(resp), nil
return (*AlarmResponse)(resp), nil
}
if isHaltErr(ctx, err) {
return nil, toErr(ctx, err)
}
} }
return nil, toErr(ctx, err)
} }
func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmResponse, error) { func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmResponse, error) {
@ -121,7 +137,7 @@ func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmR
return &ret, nil return &ret, nil
} }
resp, err := m.remote.Alarm(ctx, req, grpc.FailFast(false)) resp, err := m.remote.Alarm(ctx, req, m.callOpts...)
if err == nil { if err == nil {
return (*AlarmResponse)(resp), nil return (*AlarmResponse)(resp), nil
} }
@ -134,7 +150,7 @@ func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*Defragm
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
defer cancel() defer cancel()
resp, err := remote.Defragment(ctx, &pb.DefragmentRequest{}, grpc.FailFast(false)) resp, err := remote.Defragment(ctx, &pb.DefragmentRequest{}, m.callOpts...)
if err != nil { if err != nil {
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
@ -147,15 +163,28 @@ func (m *maintenance) Status(ctx context.Context, endpoint string) (*StatusRespo
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
defer cancel() defer cancel()
resp, err := remote.Status(ctx, &pb.StatusRequest{}, grpc.FailFast(false)) resp, err := remote.Status(ctx, &pb.StatusRequest{}, m.callOpts...)
if err != nil { if err != nil {
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
return (*StatusResponse)(resp), nil return (*StatusResponse)(resp), nil
} }
func (m *maintenance) HashKV(ctx context.Context, endpoint string, rev int64) (*HashKVResponse, error) {
remote, cancel, err := m.dial(endpoint)
if err != nil {
return nil, toErr(ctx, err)
}
defer cancel()
resp, err := remote.HashKV(ctx, &pb.HashKVRequest{Revision: rev}, m.callOpts...)
if err != nil {
return nil, toErr(ctx, err)
}
return (*HashKVResponse)(resp), nil
}
func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, error) { func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, error) {
ss, err := m.remote.Snapshot(ctx, &pb.SnapshotRequest{}, grpc.FailFast(false)) ss, err := m.remote.Snapshot(ctx, &pb.SnapshotRequest{}, m.callOpts...)
if err != nil { if err != nil {
return nil, toErr(ctx, err) return nil, toErr(ctx, err)
} }
@ -178,5 +207,20 @@ func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, error) {
} }
pw.Close() pw.Close()
}() }()
return pr, nil return &snapshotReadCloser{ctx: ctx, ReadCloser: pr}, nil
}
type snapshotReadCloser struct {
ctx context.Context
io.ReadCloser
}
func (rc *snapshotReadCloser) Read(p []byte) (n int, err error) {
n, err = rc.ReadCloser.Read(p)
return n, toErr(rc.ctx, err)
}
func (m *maintenance) MoveLeader(ctx context.Context, transfereeID uint64) (*MoveLeaderResponse, error) {
resp, err := m.remote.MoveLeader(ctx, &pb.MoveLeaderRequest{TargetID: transfereeID}, m.callOpts...)
return (*MoveLeaderResponse)(resp), toErr(ctx, err)
} }

View File

@ -75,7 +75,7 @@ type Op struct {
elseOps []Op elseOps []Op
} }
// accesors / mutators // accessors / mutators
func (op Op) IsTxn() bool { return op.t == tTxn } func (op Op) IsTxn() bool { return op.t == tTxn }
func (op Op) Txn() ([]Cmp, []Op, []Op) { return op.cmps, op.thenOps, op.elseOps } func (op Op) Txn() ([]Cmp, []Op, []Op) { return op.cmps, op.thenOps, op.elseOps }
@ -89,6 +89,39 @@ func (op *Op) WithKeyBytes(key []byte) { op.key = key }
// RangeBytes returns the byte slice holding with the Op's range end, if any. // RangeBytes returns the byte slice holding with the Op's range end, if any.
func (op Op) RangeBytes() []byte { return op.end } func (op Op) RangeBytes() []byte { return op.end }
// Rev returns the requested revision, if any.
func (op Op) Rev() int64 { return op.rev }
// IsPut returns true iff the operation is a Put.
func (op Op) IsPut() bool { return op.t == tPut }
// IsGet returns true iff the operation is a Get.
func (op Op) IsGet() bool { return op.t == tRange }
// IsDelete returns true iff the operation is a Delete.
func (op Op) IsDelete() bool { return op.t == tDeleteRange }
// IsSerializable returns true if the serializable field is true.
func (op Op) IsSerializable() bool { return op.serializable == true }
// IsKeysOnly returns whether keysOnly is set.
func (op Op) IsKeysOnly() bool { return op.keysOnly == true }
// IsCountOnly returns whether countOnly is set.
func (op Op) IsCountOnly() bool { return op.countOnly == true }
// MinModRev returns the operation's minimum modify revision.
func (op Op) MinModRev() int64 { return op.minModRev }
// MaxModRev returns the operation's maximum modify revision.
func (op Op) MaxModRev() int64 { return op.maxModRev }
// MinCreateRev returns the operation's minimum create revision.
func (op Op) MinCreateRev() int64 { return op.minCreateRev }
// MaxCreateRev returns the operation's maximum create revision.
func (op Op) MaxCreateRev() int64 { return op.maxCreateRev }
// WithRangeBytes sets the byte slice for the Op's range end. // WithRangeBytes sets the byte slice for the Op's range end.
func (op *Op) WithRangeBytes(end []byte) { op.end = end } func (op *Op) WithRangeBytes(end []byte) { op.end = end }
@ -291,9 +324,9 @@ func WithSort(target SortTarget, order SortOrder) OpOption {
if target == SortByKey && order == SortAscend { if target == SortByKey && order == SortAscend {
// If order != SortNone, server fetches the entire key-space, // If order != SortNone, server fetches the entire key-space,
// and then applies the sort and limit, if provided. // and then applies the sort and limit, if provided.
// Since current mvcc.Range implementation returns results // Since by default the server returns results sorted by keys
// sorted by keys in lexicographically ascending order, // in lexicographically ascending order, the client should ignore
// client should ignore SortOrder if the target is SortByKey. // SortOrder if the target is SortByKey.
order = SortNone order = SortNone
} }
op.sort = &SortOption{target, order} op.sort = &SortOption{target, order}
@ -434,7 +467,7 @@ func WithPrevKV() OpOption {
} }
// WithIgnoreValue updates the key using its current value. // WithIgnoreValue updates the key using its current value.
// Empty value should be passed when ignore_value is set. // This option can not be combined with non-empty values.
// Returns an error if the key does not exist. // Returns an error if the key does not exist.
func WithIgnoreValue() OpOption { func WithIgnoreValue() OpOption {
return func(op *Op) { return func(op *Op) {
@ -443,7 +476,7 @@ func WithIgnoreValue() OpOption {
} }
// WithIgnoreLease updates the key using its current lease. // WithIgnoreLease updates the key using its current lease.
// Empty lease should be passed when ignore_lease is set. // This option can not be combined with WithLease.
// Returns an error if the key does not exist. // Returns an error if the key does not exist.
func WithIgnoreLease() OpOption { func WithIgnoreLease() OpOption {
return func(op *Op) { return func(op *Op) {
@ -468,8 +501,7 @@ func (op *LeaseOp) applyOpts(opts []LeaseOption) {
} }
} }
// WithAttachedKeys requests lease timetolive API to return // WithAttachedKeys makes TimeToLive list the keys attached to the given lease ID.
// attached keys of given lease ID.
func WithAttachedKeys() LeaseOption { func WithAttachedKeys() LeaseOption {
return func(op *LeaseOp) { op.attachedKeys = true } return func(op *LeaseOp) { op.attachedKeys = true }
} }

30
vendor/github.com/coreos/etcd/clientv3/ready_wait.go generated vendored Normal file
View File

@ -0,0 +1,30 @@
// Copyright 2017 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package clientv3
import "context"
// TODO: remove this when "FailFast=false" is fixed.
// See https://github.com/grpc/grpc-go/issues/1532.
func readyWait(rpcCtx, clientCtx context.Context, ready <-chan struct{}) error {
select {
case <-ready:
return nil
case <-rpcCtx.Done():
return rpcCtx.Err()
case <-clientCtx.Done():
return clientCtx.Err()
}
}

View File

@ -15,279 +15,482 @@
package clientv3 package clientv3
import ( import (
"context"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type retryPolicy uint8
const (
repeatable retryPolicy = iota
nonRepeatable
) )
type rpcFunc func(ctx context.Context) error type rpcFunc func(ctx context.Context) error
type retryRpcFunc func(context.Context, rpcFunc) error type retryRPCFunc func(context.Context, rpcFunc, retryPolicy) error
type retryStopErrFunc func(error) bool
func (c *Client) newRetryWrapper() retryRpcFunc { // immutable requests (e.g. Get) should be retried unless it's
return func(rpcCtx context.Context, f rpcFunc) error { // an obvious server-side error (e.g. rpctypes.ErrRequestTooLarge).
//
// "isRepeatableStopError" returns "true" when an immutable request
// is interrupted by server-side or gRPC-side error and its status
// code is not transient (!= codes.Unavailable).
//
// Returning "true" means retry should stop, since client cannot
// handle itself even with retries.
func isRepeatableStopError(err error) bool {
eErr := rpctypes.Error(err)
// always stop retry on etcd errors
if serverErr, ok := eErr.(rpctypes.EtcdError); ok && serverErr.Code() != codes.Unavailable {
return true
}
// only retry if unavailable
ev, _ := status.FromError(err)
return ev.Code() != codes.Unavailable
}
// mutable requests (e.g. Put, Delete, Txn) should only be retried
// when the status code is codes.Unavailable when initial connection
// has not been established (no pinned endpoint).
//
// "isNonRepeatableStopError" returns "true" when a mutable request
// is interrupted by non-transient error that client cannot handle itself,
// or transient error while the connection has already been established
// (pinned endpoint exists).
//
// Returning "true" means retry should stop, otherwise it violates
// write-at-most-once semantics.
func isNonRepeatableStopError(err error) bool {
ev, _ := status.FromError(err)
if ev.Code() != codes.Unavailable {
return true
}
desc := rpctypes.ErrorDesc(err)
return desc != "there is no address available" && desc != "there is no connection available"
}
func (c *Client) newRetryWrapper() retryRPCFunc {
return func(rpcCtx context.Context, f rpcFunc, rp retryPolicy) error {
var isStop retryStopErrFunc
switch rp {
case repeatable:
isStop = isRepeatableStopError
case nonRepeatable:
isStop = isNonRepeatableStopError
}
for { for {
if err := readyWait(rpcCtx, c.ctx, c.balancer.ConnectNotify()); err != nil {
return err
}
pinned := c.balancer.pinned()
err := f(rpcCtx) err := f(rpcCtx)
if err == nil { if err == nil {
return nil return nil
} }
logger.Lvl(4).Infof("clientv3/retry: error %q on pinned endpoint %q", err.Error(), pinned)
eErr := rpctypes.Error(err) if s, ok := status.FromError(err); ok && (s.Code() == codes.Unavailable || s.Code() == codes.DeadlineExceeded || s.Code() == codes.Internal) {
// always stop retry on etcd errors // mark this before endpoint switch is triggered
if _, ok := eErr.(rpctypes.EtcdError); ok { c.balancer.hostPortError(pinned, err)
return err c.balancer.next()
logger.Lvl(4).Infof("clientv3/retry: switching from %q due to error %q", pinned, err.Error())
} }
// only retry if unavailable if isStop(err) {
if grpc.Code(err) != codes.Unavailable {
return err return err
} }
select {
case <-c.balancer.ConnectNotify():
case <-rpcCtx.Done():
return rpcCtx.Err()
case <-c.ctx.Done():
return c.ctx.Err()
}
} }
} }
} }
func (c *Client) newAuthRetryWrapper() retryRpcFunc { func (c *Client) newAuthRetryWrapper(retryf retryRPCFunc) retryRPCFunc {
return func(rpcCtx context.Context, f rpcFunc) error { return func(rpcCtx context.Context, f rpcFunc, rp retryPolicy) error {
for { for {
err := f(rpcCtx) pinned := c.balancer.pinned()
err := retryf(rpcCtx, f, rp)
if err == nil { if err == nil {
return nil return nil
} }
logger.Lvl(4).Infof("clientv3/auth-retry: error %q on pinned endpoint %q", err.Error(), pinned)
// always stop retry on etcd errors other than invalid auth token // always stop retry on etcd errors other than invalid auth token
if rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken { if rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken {
gterr := c.getToken(rpcCtx) gterr := c.getToken(rpcCtx)
if gterr != nil { if gterr != nil {
logger.Lvl(4).Infof("clientv3/auth-retry: cannot retry due to error %q(%q) on pinned endpoint %q", err.Error(), gterr.Error(), pinned)
return err // return the original error for simplicity return err // return the original error for simplicity
} }
continue continue
} }
return err return err
} }
} }
} }
// RetryKVClient implements a KVClient that uses the client's FailFast retry policy.
func RetryKVClient(c *Client) pb.KVClient {
retryWrite := &retryWriteKVClient{pb.NewKVClient(c.conn), c.retryWrapper}
return &retryKVClient{&retryWriteKVClient{retryWrite, c.retryAuthWrapper}}
}
type retryKVClient struct { type retryKVClient struct {
*retryWriteKVClient kc pb.KVClient
retryf retryRPCFunc
} }
// RetryKVClient implements a KVClient.
func RetryKVClient(c *Client) pb.KVClient {
return &retryKVClient{
kc: pb.NewKVClient(c.conn),
retryf: c.newAuthRetryWrapper(c.newRetryWrapper()),
}
}
func (rkv *retryKVClient) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (resp *pb.RangeResponse, err error) { func (rkv *retryKVClient) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (resp *pb.RangeResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error { err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.retryWriteKVClient.Range(rctx, in, opts...) resp, err = rkv.kc.Range(rctx, in, opts...)
return err return err
}) }, repeatable)
return resp, err return resp, err
} }
type retryWriteKVClient struct { func (rkv *retryKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) {
pb.KVClient
retryf retryRpcFunc
}
func (rkv *retryWriteKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error { err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.KVClient.Put(rctx, in, opts...) resp, err = rkv.kc.Put(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rkv *retryWriteKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) { func (rkv *retryKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error { err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.KVClient.DeleteRange(rctx, in, opts...) resp, err = rkv.kc.DeleteRange(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rkv *retryWriteKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) { func (rkv *retryKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) {
// TODO: "repeatable" for read-only txn
err = rkv.retryf(ctx, func(rctx context.Context) error { err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.KVClient.Txn(rctx, in, opts...) resp, err = rkv.kc.Txn(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rkv *retryWriteKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) { func (rkv *retryKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error { err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.KVClient.Compact(rctx, in, opts...) resp, err = rkv.kc.Compact(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
type retryLeaseClient struct { type retryLeaseClient struct {
pb.LeaseClient lc pb.LeaseClient
retryf retryRpcFunc retryf retryRPCFunc
} }
// RetryLeaseClient implements a LeaseClient that uses the client's FailFast retry policy. // RetryLeaseClient implements a LeaseClient.
func RetryLeaseClient(c *Client) pb.LeaseClient { func RetryLeaseClient(c *Client) pb.LeaseClient {
retry := &retryLeaseClient{pb.NewLeaseClient(c.conn), c.retryWrapper} return &retryLeaseClient{
return &retryLeaseClient{retry, c.retryAuthWrapper} lc: pb.NewLeaseClient(c.conn),
retryf: c.newAuthRetryWrapper(c.newRetryWrapper()),
}
}
func (rlc *retryLeaseClient) LeaseTimeToLive(ctx context.Context, in *pb.LeaseTimeToLiveRequest, opts ...grpc.CallOption) (resp *pb.LeaseTimeToLiveResponse, err error) {
err = rlc.retryf(ctx, func(rctx context.Context) error {
resp, err = rlc.lc.LeaseTimeToLive(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rlc *retryLeaseClient) LeaseLeases(ctx context.Context, in *pb.LeaseLeasesRequest, opts ...grpc.CallOption) (resp *pb.LeaseLeasesResponse, err error) {
err = rlc.retryf(ctx, func(rctx context.Context) error {
resp, err = rlc.lc.LeaseLeases(rctx, in, opts...)
return err
}, repeatable)
return resp, err
} }
func (rlc *retryLeaseClient) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRequest, opts ...grpc.CallOption) (resp *pb.LeaseGrantResponse, err error) { func (rlc *retryLeaseClient) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRequest, opts ...grpc.CallOption) (resp *pb.LeaseGrantResponse, err error) {
err = rlc.retryf(ctx, func(rctx context.Context) error { err = rlc.retryf(ctx, func(rctx context.Context) error {
resp, err = rlc.LeaseClient.LeaseGrant(rctx, in, opts...) resp, err = rlc.lc.LeaseGrant(rctx, in, opts...)
return err return err
}) }, repeatable)
return resp, err return resp, err
} }
func (rlc *retryLeaseClient) LeaseRevoke(ctx context.Context, in *pb.LeaseRevokeRequest, opts ...grpc.CallOption) (resp *pb.LeaseRevokeResponse, err error) { func (rlc *retryLeaseClient) LeaseRevoke(ctx context.Context, in *pb.LeaseRevokeRequest, opts ...grpc.CallOption) (resp *pb.LeaseRevokeResponse, err error) {
err = rlc.retryf(ctx, func(rctx context.Context) error { err = rlc.retryf(ctx, func(rctx context.Context) error {
resp, err = rlc.LeaseClient.LeaseRevoke(rctx, in, opts...) resp, err = rlc.lc.LeaseRevoke(rctx, in, opts...)
return err return err
}) }, repeatable)
return resp, err return resp, err
} }
type retryClusterClient struct { func (rlc *retryLeaseClient) LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (stream pb.Lease_LeaseKeepAliveClient, err error) {
pb.ClusterClient err = rlc.retryf(ctx, func(rctx context.Context) error {
retryf retryRpcFunc stream, err = rlc.lc.LeaseKeepAlive(rctx, opts...)
return err
}, repeatable)
return stream, err
} }
// RetryClusterClient implements a ClusterClient that uses the client's FailFast retry policy. type retryClusterClient struct {
cc pb.ClusterClient
retryf retryRPCFunc
}
// RetryClusterClient implements a ClusterClient.
func RetryClusterClient(c *Client) pb.ClusterClient { func RetryClusterClient(c *Client) pb.ClusterClient {
return &retryClusterClient{pb.NewClusterClient(c.conn), c.retryWrapper} return &retryClusterClient{
cc: pb.NewClusterClient(c.conn),
retryf: c.newRetryWrapper(),
}
}
func (rcc *retryClusterClient) MemberList(ctx context.Context, in *pb.MemberListRequest, opts ...grpc.CallOption) (resp *pb.MemberListResponse, err error) {
err = rcc.retryf(ctx, func(rctx context.Context) error {
resp, err = rcc.cc.MemberList(rctx, in, opts...)
return err
}, repeatable)
return resp, err
} }
func (rcc *retryClusterClient) MemberAdd(ctx context.Context, in *pb.MemberAddRequest, opts ...grpc.CallOption) (resp *pb.MemberAddResponse, err error) { func (rcc *retryClusterClient) MemberAdd(ctx context.Context, in *pb.MemberAddRequest, opts ...grpc.CallOption) (resp *pb.MemberAddResponse, err error) {
err = rcc.retryf(ctx, func(rctx context.Context) error { err = rcc.retryf(ctx, func(rctx context.Context) error {
resp, err = rcc.ClusterClient.MemberAdd(rctx, in, opts...) resp, err = rcc.cc.MemberAdd(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rcc *retryClusterClient) MemberRemove(ctx context.Context, in *pb.MemberRemoveRequest, opts ...grpc.CallOption) (resp *pb.MemberRemoveResponse, err error) { func (rcc *retryClusterClient) MemberRemove(ctx context.Context, in *pb.MemberRemoveRequest, opts ...grpc.CallOption) (resp *pb.MemberRemoveResponse, err error) {
err = rcc.retryf(ctx, func(rctx context.Context) error { err = rcc.retryf(ctx, func(rctx context.Context) error {
resp, err = rcc.ClusterClient.MemberRemove(rctx, in, opts...) resp, err = rcc.cc.MemberRemove(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rcc *retryClusterClient) MemberUpdate(ctx context.Context, in *pb.MemberUpdateRequest, opts ...grpc.CallOption) (resp *pb.MemberUpdateResponse, err error) { func (rcc *retryClusterClient) MemberUpdate(ctx context.Context, in *pb.MemberUpdateRequest, opts ...grpc.CallOption) (resp *pb.MemberUpdateResponse, err error) {
err = rcc.retryf(ctx, func(rctx context.Context) error { err = rcc.retryf(ctx, func(rctx context.Context) error {
resp, err = rcc.ClusterClient.MemberUpdate(rctx, in, opts...) resp, err = rcc.cc.MemberUpdate(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err
}
type retryMaintenanceClient struct {
mc pb.MaintenanceClient
retryf retryRPCFunc
}
// RetryMaintenanceClient implements a Maintenance.
func RetryMaintenanceClient(c *Client, conn *grpc.ClientConn) pb.MaintenanceClient {
return &retryMaintenanceClient{
mc: pb.NewMaintenanceClient(conn),
retryf: c.newRetryWrapper(),
}
}
func (rmc *retryMaintenanceClient) Alarm(ctx context.Context, in *pb.AlarmRequest, opts ...grpc.CallOption) (resp *pb.AlarmResponse, err error) {
err = rmc.retryf(ctx, func(rctx context.Context) error {
resp, err = rmc.mc.Alarm(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rmc *retryMaintenanceClient) Status(ctx context.Context, in *pb.StatusRequest, opts ...grpc.CallOption) (resp *pb.StatusResponse, err error) {
err = rmc.retryf(ctx, func(rctx context.Context) error {
resp, err = rmc.mc.Status(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rmc *retryMaintenanceClient) Hash(ctx context.Context, in *pb.HashRequest, opts ...grpc.CallOption) (resp *pb.HashResponse, err error) {
err = rmc.retryf(ctx, func(rctx context.Context) error {
resp, err = rmc.mc.Hash(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rmc *retryMaintenanceClient) HashKV(ctx context.Context, in *pb.HashKVRequest, opts ...grpc.CallOption) (resp *pb.HashKVResponse, err error) {
err = rmc.retryf(ctx, func(rctx context.Context) error {
resp, err = rmc.mc.HashKV(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rmc *retryMaintenanceClient) Snapshot(ctx context.Context, in *pb.SnapshotRequest, opts ...grpc.CallOption) (stream pb.Maintenance_SnapshotClient, err error) {
err = rmc.retryf(ctx, func(rctx context.Context) error {
stream, err = rmc.mc.Snapshot(rctx, in, opts...)
return err
}, repeatable)
return stream, err
}
func (rmc *retryMaintenanceClient) MoveLeader(ctx context.Context, in *pb.MoveLeaderRequest, opts ...grpc.CallOption) (resp *pb.MoveLeaderResponse, err error) {
err = rmc.retryf(ctx, func(rctx context.Context) error {
resp, err = rmc.mc.MoveLeader(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rmc *retryMaintenanceClient) Defragment(ctx context.Context, in *pb.DefragmentRequest, opts ...grpc.CallOption) (resp *pb.DefragmentResponse, err error) {
err = rmc.retryf(ctx, func(rctx context.Context) error {
resp, err = rmc.mc.Defragment(rctx, in, opts...)
return err
}, nonRepeatable)
return resp, err return resp, err
} }
type retryAuthClient struct { type retryAuthClient struct {
pb.AuthClient ac pb.AuthClient
retryf retryRpcFunc retryf retryRPCFunc
} }
// RetryAuthClient implements a AuthClient that uses the client's FailFast retry policy. // RetryAuthClient implements a AuthClient.
func RetryAuthClient(c *Client) pb.AuthClient { func RetryAuthClient(c *Client) pb.AuthClient {
return &retryAuthClient{pb.NewAuthClient(c.conn), c.retryWrapper} return &retryAuthClient{
ac: pb.NewAuthClient(c.conn),
retryf: c.newRetryWrapper(),
}
}
func (rac *retryAuthClient) UserList(ctx context.Context, in *pb.AuthUserListRequest, opts ...grpc.CallOption) (resp *pb.AuthUserListResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.ac.UserList(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rac *retryAuthClient) UserGet(ctx context.Context, in *pb.AuthUserGetRequest, opts ...grpc.CallOption) (resp *pb.AuthUserGetResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.ac.UserGet(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rac *retryAuthClient) RoleGet(ctx context.Context, in *pb.AuthRoleGetRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleGetResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.ac.RoleGet(rctx, in, opts...)
return err
}, repeatable)
return resp, err
}
func (rac *retryAuthClient) RoleList(ctx context.Context, in *pb.AuthRoleListRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleListResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.ac.RoleList(rctx, in, opts...)
return err
}, repeatable)
return resp, err
} }
func (rac *retryAuthClient) AuthEnable(ctx context.Context, in *pb.AuthEnableRequest, opts ...grpc.CallOption) (resp *pb.AuthEnableResponse, err error) { func (rac *retryAuthClient) AuthEnable(ctx context.Context, in *pb.AuthEnableRequest, opts ...grpc.CallOption) (resp *pb.AuthEnableResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.AuthEnable(rctx, in, opts...) resp, err = rac.ac.AuthEnable(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) AuthDisable(ctx context.Context, in *pb.AuthDisableRequest, opts ...grpc.CallOption) (resp *pb.AuthDisableResponse, err error) { func (rac *retryAuthClient) AuthDisable(ctx context.Context, in *pb.AuthDisableRequest, opts ...grpc.CallOption) (resp *pb.AuthDisableResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.AuthDisable(rctx, in, opts...) resp, err = rac.ac.AuthDisable(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) UserAdd(ctx context.Context, in *pb.AuthUserAddRequest, opts ...grpc.CallOption) (resp *pb.AuthUserAddResponse, err error) { func (rac *retryAuthClient) UserAdd(ctx context.Context, in *pb.AuthUserAddRequest, opts ...grpc.CallOption) (resp *pb.AuthUserAddResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.UserAdd(rctx, in, opts...) resp, err = rac.ac.UserAdd(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) UserDelete(ctx context.Context, in *pb.AuthUserDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthUserDeleteResponse, err error) { func (rac *retryAuthClient) UserDelete(ctx context.Context, in *pb.AuthUserDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthUserDeleteResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.UserDelete(rctx, in, opts...) resp, err = rac.ac.UserDelete(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) UserChangePassword(ctx context.Context, in *pb.AuthUserChangePasswordRequest, opts ...grpc.CallOption) (resp *pb.AuthUserChangePasswordResponse, err error) { func (rac *retryAuthClient) UserChangePassword(ctx context.Context, in *pb.AuthUserChangePasswordRequest, opts ...grpc.CallOption) (resp *pb.AuthUserChangePasswordResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.UserChangePassword(rctx, in, opts...) resp, err = rac.ac.UserChangePassword(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) UserGrantRole(ctx context.Context, in *pb.AuthUserGrantRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserGrantRoleResponse, err error) { func (rac *retryAuthClient) UserGrantRole(ctx context.Context, in *pb.AuthUserGrantRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserGrantRoleResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.UserGrantRole(rctx, in, opts...) resp, err = rac.ac.UserGrantRole(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) UserRevokeRole(ctx context.Context, in *pb.AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserRevokeRoleResponse, err error) { func (rac *retryAuthClient) UserRevokeRole(ctx context.Context, in *pb.AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserRevokeRoleResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.UserRevokeRole(rctx, in, opts...) resp, err = rac.ac.UserRevokeRole(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) RoleAdd(ctx context.Context, in *pb.AuthRoleAddRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleAddResponse, err error) { func (rac *retryAuthClient) RoleAdd(ctx context.Context, in *pb.AuthRoleAddRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleAddResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.RoleAdd(rctx, in, opts...) resp, err = rac.ac.RoleAdd(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) RoleDelete(ctx context.Context, in *pb.AuthRoleDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleDeleteResponse, err error) { func (rac *retryAuthClient) RoleDelete(ctx context.Context, in *pb.AuthRoleDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleDeleteResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.RoleDelete(rctx, in, opts...) resp, err = rac.ac.RoleDelete(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) RoleGrantPermission(ctx context.Context, in *pb.AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleGrantPermissionResponse, err error) { func (rac *retryAuthClient) RoleGrantPermission(ctx context.Context, in *pb.AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleGrantPermissionResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.RoleGrantPermission(rctx, in, opts...) resp, err = rac.ac.RoleGrantPermission(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err return resp, err
} }
func (rac *retryAuthClient) RoleRevokePermission(ctx context.Context, in *pb.AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleRevokePermissionResponse, err error) { func (rac *retryAuthClient) RoleRevokePermission(ctx context.Context, in *pb.AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleRevokePermissionResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error { err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.AuthClient.RoleRevokePermission(rctx, in, opts...) resp, err = rac.ac.RoleRevokePermission(rctx, in, opts...)
return err return err
}) }, nonRepeatable)
return resp, err
}
func (rac *retryAuthClient) Authenticate(ctx context.Context, in *pb.AuthenticateRequest, opts ...grpc.CallOption) (resp *pb.AuthenticateResponse, err error) {
err = rac.retryf(ctx, func(rctx context.Context) error {
resp, err = rac.ac.Authenticate(rctx, in, opts...)
return err
}, nonRepeatable)
return resp, err return resp, err
} }

View File

@ -15,16 +15,17 @@
package clientv3 package clientv3
import ( import (
"context"
"sync" "sync"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
// Txn is the interface that wraps mini-transactions. // Txn is the interface that wraps mini-transactions.
// //
// Tx.If( // Txn(context.TODO()).If(
// Compare(Value(k1), ">", v1), // Compare(Value(k1), ">", v1),
// Compare(Version(k1), "=", 2) // Compare(Version(k1), "=", 2)
// ).Then( // ).Then(
@ -66,6 +67,8 @@ type txn struct {
sus []*pb.RequestOp sus []*pb.RequestOp
fas []*pb.RequestOp fas []*pb.RequestOp
callOpts []grpc.CallOption
} }
func (txn *txn) If(cs ...Cmp) Txn { func (txn *txn) If(cs ...Cmp) Txn {
@ -135,30 +138,14 @@ func (txn *txn) Else(ops ...Op) Txn {
func (txn *txn) Commit() (*TxnResponse, error) { func (txn *txn) Commit() (*TxnResponse, error) {
txn.mu.Lock() txn.mu.Lock()
defer txn.mu.Unlock() defer txn.mu.Unlock()
for {
resp, err := txn.commit()
if err == nil {
return resp, err
}
if isHaltErr(txn.ctx, err) {
return nil, toErr(txn.ctx, err)
}
if txn.isWrite {
return nil, toErr(txn.ctx, err)
}
}
}
func (txn *txn) commit() (*TxnResponse, error) {
r := &pb.TxnRequest{Compare: txn.cmps, Success: txn.sus, Failure: txn.fas} r := &pb.TxnRequest{Compare: txn.cmps, Success: txn.sus, Failure: txn.fas}
var opts []grpc.CallOption var resp *pb.TxnResponse
if !txn.isWrite { var err error
opts = []grpc.CallOption{grpc.FailFast(false)} resp, err = txn.kv.remote.Txn(txn.ctx, r, txn.callOpts...)
}
resp, err := txn.kv.remote.Txn(txn.ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, toErr(txn.ctx, err)
} }
return (*TxnResponse)(resp), nil return (*TxnResponse)(resp), nil
} }

View File

@ -15,6 +15,7 @@
package clientv3 package clientv3
import ( import (
"context"
"fmt" "fmt"
"sync" "sync"
"time" "time"
@ -22,9 +23,11 @@ import (
v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
mvccpb "github.com/coreos/etcd/mvcc/mvccpb" mvccpb "github.com/coreos/etcd/mvcc/mvccpb"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
) )
const ( const (
@ -89,7 +92,7 @@ func (wr *WatchResponse) Err() error {
return v3rpc.ErrCompacted return v3rpc.ErrCompacted
case wr.Canceled: case wr.Canceled:
if len(wr.cancelReason) != 0 { if len(wr.cancelReason) != 0 {
return v3rpc.Error(grpc.Errorf(codes.FailedPrecondition, "%s", wr.cancelReason)) return v3rpc.Error(status.Error(codes.FailedPrecondition, wr.cancelReason))
} }
return v3rpc.ErrFutureRev return v3rpc.ErrFutureRev
} }
@ -103,7 +106,8 @@ func (wr *WatchResponse) IsProgressNotify() bool {
// watcher implements the Watcher interface // watcher implements the Watcher interface
type watcher struct { type watcher struct {
remote pb.WatchClient remote pb.WatchClient
callOpts []grpc.CallOption
// mu protects the grpc streams map // mu protects the grpc streams map
mu sync.RWMutex mu sync.RWMutex
@ -114,8 +118,9 @@ type watcher struct {
// watchGrpcStream tracks all watch resources attached to a single grpc stream. // watchGrpcStream tracks all watch resources attached to a single grpc stream.
type watchGrpcStream struct { type watchGrpcStream struct {
owner *watcher owner *watcher
remote pb.WatchClient remote pb.WatchClient
callOpts []grpc.CallOption
// ctx controls internal remote.Watch requests // ctx controls internal remote.Watch requests
ctx context.Context ctx context.Context
@ -134,7 +139,7 @@ type watchGrpcStream struct {
respc chan *pb.WatchResponse respc chan *pb.WatchResponse
// donec closes to broadcast shutdown // donec closes to broadcast shutdown
donec chan struct{} donec chan struct{}
// errc transmits errors from grpc Recv to the watch stream reconn logic // errc transmits errors from grpc Recv to the watch stream reconnect logic
errc chan error errc chan error
// closingc gets the watcherStream of closing watchers // closingc gets the watcherStream of closing watchers
closingc chan *watcherStream closingc chan *watcherStream
@ -186,14 +191,18 @@ type watcherStream struct {
} }
func NewWatcher(c *Client) Watcher { func NewWatcher(c *Client) Watcher {
return NewWatchFromWatchClient(pb.NewWatchClient(c.conn)) return NewWatchFromWatchClient(pb.NewWatchClient(c.conn), c)
} }
func NewWatchFromWatchClient(wc pb.WatchClient) Watcher { func NewWatchFromWatchClient(wc pb.WatchClient, c *Client) Watcher {
return &watcher{ w := &watcher{
remote: wc, remote: wc,
streams: make(map[string]*watchGrpcStream), streams: make(map[string]*watchGrpcStream),
} }
if c != nil {
w.callOpts = c.callOpts
}
return w
} }
// never closes // never closes
@ -212,17 +221,17 @@ func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream {
wgs := &watchGrpcStream{ wgs := &watchGrpcStream{
owner: w, owner: w,
remote: w.remote, remote: w.remote,
callOpts: w.callOpts,
ctx: ctx, ctx: ctx,
ctxKey: fmt.Sprintf("%v", inctx), ctxKey: streamKeyFromCtx(inctx),
cancel: cancel, cancel: cancel,
substreams: make(map[int64]*watcherStream), substreams: make(map[int64]*watcherStream),
respc: make(chan *pb.WatchResponse),
respc: make(chan *pb.WatchResponse), reqc: make(chan *watchRequest),
reqc: make(chan *watchRequest), donec: make(chan struct{}),
donec: make(chan struct{}), errc: make(chan error, 1),
errc: make(chan error, 1), closingc: make(chan *watcherStream),
closingc: make(chan *watcherStream), resumec: make(chan struct{}),
resumec: make(chan struct{}),
} }
go wgs.run() go wgs.run()
return wgs return wgs
@ -253,7 +262,7 @@ func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) Watch
} }
ok := false ok := false
ctxKey := fmt.Sprintf("%v", ctx) ctxKey := streamKeyFromCtx(ctx)
// find or allocate appropriate grpc watch stream // find or allocate appropriate grpc watch stream
w.mu.Lock() w.mu.Lock()
@ -434,7 +443,7 @@ func (w *watchGrpcStream) run() {
initReq: *wreq, initReq: *wreq,
id: -1, id: -1,
outc: outc, outc: outc,
// unbufffered so resumes won't cause repeat events // unbuffered so resumes won't cause repeat events
recvc: make(chan *WatchResponse), recvc: make(chan *WatchResponse),
} }
@ -461,7 +470,7 @@ func (w *watchGrpcStream) run() {
if ws := w.nextResume(); ws != nil { if ws := w.nextResume(); ws != nil {
wc.Send(ws.initReq.toPB()) wc.Send(ws.initReq.toPB())
} }
case pbresp.Canceled: case pbresp.Canceled && pbresp.CompactRevision == 0:
delete(cancelSet, pbresp.WatchId) delete(cancelSet, pbresp.WatchId)
if ws, ok := w.substreams[pbresp.WatchId]; ok { if ws, ok := w.substreams[pbresp.WatchId]; ok {
// signal to stream goroutine to update closingc // signal to stream goroutine to update closingc
@ -486,7 +495,7 @@ func (w *watchGrpcStream) run() {
req := &pb.WatchRequest{RequestUnion: cr} req := &pb.WatchRequest{RequestUnion: cr}
wc.Send(req) wc.Send(req)
} }
// watch client failed to recv; spawn another if possible // watch client failed on Recv; spawn another if possible
case err := <-w.errc: case err := <-w.errc:
if isHaltErr(w.ctx, err) || toErr(w.ctx, err) == v3rpc.ErrNoLeader { if isHaltErr(w.ctx, err) || toErr(w.ctx, err) == v3rpc.ErrNoLeader {
closeErr = err closeErr = err
@ -748,7 +757,7 @@ func (w *watchGrpcStream) waitCancelSubstreams(stopc <-chan struct{}) <-chan str
return donec return donec
} }
// joinSubstream waits for all substream goroutines to complete // joinSubstreams waits for all substream goroutines to complete.
func (w *watchGrpcStream) joinSubstreams() { func (w *watchGrpcStream) joinSubstreams() {
for _, ws := range w.substreams { for _, ws := range w.substreams {
<-ws.donec <-ws.donec
@ -760,7 +769,9 @@ func (w *watchGrpcStream) joinSubstreams() {
} }
} }
// openWatchClient retries opening a watchclient until retryConnection fails // openWatchClient retries opening a watch client until success or halt.
// manually retry in case "ws==nil && err==nil"
// TODO: remove FailFast=false
func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error) { func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error) {
for { for {
select { select {
@ -771,7 +782,7 @@ func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error)
return nil, err return nil, err
default: default:
} }
if ws, err = w.remote.Watch(w.ctx, grpc.FailFast(false)); ws != nil && err == nil { if ws, err = w.remote.Watch(w.ctx, w.callOpts...); ws != nil && err == nil {
break break
} }
if isHaltErr(w.ctx, err) { if isHaltErr(w.ctx, err) {
@ -781,7 +792,7 @@ func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error)
return ws, nil return ws, nil
} }
// toPB converts an internal watch request structure to its protobuf messagefunc (wr *watchRequest) // toPB converts an internal watch request structure to its protobuf WatchRequest structure.
func (wr *watchRequest) toPB() *pb.WatchRequest { func (wr *watchRequest) toPB() *pb.WatchRequest {
req := &pb.WatchCreateRequest{ req := &pb.WatchCreateRequest{
StartRevision: wr.rev, StartRevision: wr.rev,
@ -794,3 +805,10 @@ func (wr *watchRequest) toPB() *pb.WatchRequest {
cr := &pb.WatchRequest_CreateRequest{CreateRequest: req} cr := &pb.WatchRequest_CreateRequest{CreateRequest: req}
return &pb.WatchRequest{RequestUnion: cr} return &pb.WatchRequest{RequestUnion: cr}
} }
func streamKeyFromCtx(ctx context.Context) string {
if md, ok := metadata.FromOutgoingContext(ctx); ok {
return fmt.Sprintf("%+v", md)
}
return ""
}

Some files were not shown because too many files have changed in this diff Show More