From 55b37261bc2810232d1041737f177ba37d2b8f27 Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Mon, 9 Sep 2019 16:31:32 -0400 Subject: [PATCH 01/33] ETCDCTL_README: clarify the usage of ETCDCTL_* variables fixes # 10840 --- etcdctl/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etcdctl/README.md b/etcdctl/README.md index 1557be54c..13f528498 100644 --- a/etcdctl/README.md +++ b/etcdctl/README.md @@ -16,7 +16,7 @@ ETCDCTL_CERT=/tmp/cert.pem ETCDCTL_KEY=/tmp/key.pem ``` -Prefix flag strings with `ETCDCTL_`, convert all letters to upper-case, and replace dash(`-`) with underscore(`_`). +Prefix flag strings with `ETCDCTL_`, convert all letters to upper-case, and replace dash(`-`) with underscore(`_`). Note that the environment variables with the prefix `ETCDCTL_` can only be used with the etcdctl global flags. Also, the environment variable `ETCDCTL_API` is a special case variable for etcdctl internal use only. ## Key-value commands From 04ddfa8b8dab4ac50dfac8386364d07b79496daf Mon Sep 17 00:00:00 2001 From: vimalk78 Date: Mon, 2 Sep 2019 19:45:27 +0100 Subject: [PATCH 02/33] clientv3/concurrency: Added Mutex.TryLock() TryLock locks the mutex if not already locked by another session. If lock is held by another session, return immediately after attempting necessary cleanup Added integration test Fixes #10493 --- clientv3/concurrency/example_mutex_test.go | 51 ++++++++++++++++ clientv3/concurrency/mutex.go | 70 ++++++++++++++++------ integration/v3_lock_test.go | 70 +++++++++++++++++++--- 3 files changed, 167 insertions(+), 24 deletions(-) diff --git a/clientv3/concurrency/example_mutex_test.go b/clientv3/concurrency/example_mutex_test.go index a0463d5b5..6b55340cf 100644 --- a/clientv3/concurrency/example_mutex_test.go +++ b/clientv3/concurrency/example_mutex_test.go @@ -23,6 +23,57 @@ import ( "go.etcd.io/etcd/clientv3/concurrency" ) +func ExampleMutex_TryLock() { + cli, err := clientv3.New(clientv3.Config{Endpoints: endpoints}) + if err != nil { + log.Fatal(err) + } + defer cli.Close() + + // create two separate sessions for lock competition + s1, err := concurrency.NewSession(cli) + if err != nil { + log.Fatal(err) + } + defer s1.Close() + m1 := concurrency.NewMutex(s1, "/my-lock/") + + s2, err := concurrency.NewSession(cli) + if err != nil { + log.Fatal(err) + } + defer s2.Close() + m2 := concurrency.NewMutex(s2, "/my-lock/") + + // acquire lock for s1 + if err = m1.Lock(context.TODO()); err != nil { + log.Fatal(err) + } + fmt.Println("acquired lock for s1") + + if err = m2.TryLock(context.TODO()); err == nil { + log.Fatal("should not acquire lock") + } + if err == concurrency.ErrLocked { + fmt.Println("cannot acquire lock for s2, as already locked in another session") + } + + if err = m1.Unlock(context.TODO()); err != nil { + log.Fatal(err) + } + fmt.Println("released lock for s1") + if err = m2.TryLock(context.TODO()); err != nil { + log.Fatal(err) + } + fmt.Println("acquired lock for s2") + + // Output: + // acquired lock for s1 + // cannot acquire lock for s2, as already locked in another session + // released lock for s1 + // acquired lock for s2 +} + func ExampleMutex_Lock() { cli, err := clientv3.New(clientv3.Config{Endpoints: endpoints}) if err != nil { diff --git a/clientv3/concurrency/mutex.go b/clientv3/concurrency/mutex.go index 013534193..306470b88 100644 --- a/clientv3/concurrency/mutex.go +++ b/clientv3/concurrency/mutex.go @@ -16,6 +16,7 @@ package concurrency import ( "context" + "errors" "fmt" "sync" @@ -23,6 +24,9 @@ import ( pb "go.etcd.io/etcd/etcdserver/etcdserverpb" ) +// ErrLocked is returned by TryLock when Mutex is already locked by another session. +var ErrLocked = errors.New("mutex: Locked by another session") + // Mutex implements the sync Locker interface with etcd type Mutex struct { s *Session @@ -37,9 +41,56 @@ func NewMutex(s *Session, pfx string) *Mutex { return &Mutex{s, pfx + "/", "", -1, nil} } +// TryLock locks the mutex if not already locked by another session. +// If lock is held by another session, return immediately after attempting necessary cleanup +// The ctx argument is used for the sending/receiving Txn RPC. +func (m *Mutex) TryLock(ctx context.Context) error { + resp, err := m.tryAcquire(ctx) + if err != nil { + return err + } + // if no key on prefix / the minimum rev is key, already hold the lock + ownerKey := resp.Responses[1].GetResponseRange().Kvs + if len(ownerKey) == 0 || ownerKey[0].CreateRevision == m.myRev { + m.hdr = resp.Header + return nil + } + client := m.s.Client() + // Cannot lock, so delete the key + if _, err := client.Delete(ctx, m.myKey); err != nil { + return err + } + m.myKey = "\x00" + m.myRev = -1 + return ErrLocked +} + // Lock locks the mutex with a cancelable context. If the context is canceled // while trying to acquire the lock, the mutex tries to clean its stale lock entry. func (m *Mutex) Lock(ctx context.Context) error { + resp, err := m.tryAcquire(ctx) + if err != nil { + return err + } + // if no key on prefix / the minimum rev is key, already hold the lock + ownerKey := resp.Responses[1].GetResponseRange().Kvs + if len(ownerKey) == 0 || ownerKey[0].CreateRevision == m.myRev { + m.hdr = resp.Header + return nil + } + client := m.s.Client() + // wait for deletion revisions prior to myKey + hdr, werr := waitDeletes(ctx, client, m.pfx, m.myRev-1) + // release lock key if wait failed + if werr != nil { + m.Unlock(client.Ctx()) + } else { + m.hdr = hdr + } + return werr +} + +func (m *Mutex) tryAcquire(ctx context.Context) (*v3.TxnResponse, error) { s := m.s client := m.s.Client() @@ -53,28 +104,13 @@ func (m *Mutex) Lock(ctx context.Context) error { getOwner := v3.OpGet(m.pfx, v3.WithFirstCreate()...) resp, err := client.Txn(ctx).If(cmp).Then(put, getOwner).Else(get, getOwner).Commit() if err != nil { - return err + return nil, err } m.myRev = resp.Header.Revision if !resp.Succeeded { m.myRev = resp.Responses[0].GetResponseRange().Kvs[0].CreateRevision } - // if no key on prefix / the minimum rev is key, already hold the lock - ownerKey := resp.Responses[1].GetResponseRange().Kvs - if len(ownerKey) == 0 || ownerKey[0].CreateRevision == m.myRev { - m.hdr = resp.Header - return nil - } - - // wait for deletion revisions prior to myKey - hdr, werr := waitDeletes(ctx, client, m.pfx, m.myRev-1) - // release lock key if wait failed - if werr != nil { - m.Unlock(client.Ctx()) - } else { - m.hdr = hdr - } - return werr + return resp, nil } func (m *Mutex) Unlock(ctx context.Context) error { diff --git a/integration/v3_lock_test.go b/integration/v3_lock_test.go index 88e032796..e36af2d43 100644 --- a/integration/v3_lock_test.go +++ b/integration/v3_lock_test.go @@ -23,30 +23,30 @@ import ( "go.etcd.io/etcd/clientv3" "go.etcd.io/etcd/clientv3/concurrency" - "go.etcd.io/etcd/contrib/recipes" + recipe "go.etcd.io/etcd/contrib/recipes" "go.etcd.io/etcd/mvcc/mvccpb" "go.etcd.io/etcd/pkg/testutil" ) -func TestMutexSingleNode(t *testing.T) { +func TestMutexLockSingleNode(t *testing.T) { clus := NewClusterV3(t, &ClusterConfig{Size: 3}) defer clus.Terminate(t) var clients []*clientv3.Client - testMutex(t, 5, makeSingleNodeClients(t, clus.cluster, &clients)) + testMutexLock(t, 5, makeSingleNodeClients(t, clus.cluster, &clients)) closeClients(t, clients) } -func TestMutexMultiNode(t *testing.T) { +func TestMutexLockMultiNode(t *testing.T) { clus := NewClusterV3(t, &ClusterConfig{Size: 3}) defer clus.Terminate(t) var clients []*clientv3.Client - testMutex(t, 5, makeMultiNodeClients(t, clus.cluster, &clients)) + testMutexLock(t, 5, makeMultiNodeClients(t, clus.cluster, &clients)) closeClients(t, clients) } -func testMutex(t *testing.T, waiters int, chooseClient func() *clientv3.Client) { +func testMutexLock(t *testing.T, waiters int, chooseClient func() *clientv3.Client) { // stream lock acquisitions lockedC := make(chan *concurrency.Mutex) for i := 0; i < waiters; i++ { @@ -82,6 +82,62 @@ func testMutex(t *testing.T, waiters int, chooseClient func() *clientv3.Client) } } +func TestMutexTryLockSingleNode(t *testing.T) { + clus := NewClusterV3(t, &ClusterConfig{Size: 3}) + defer clus.Terminate(t) + + var clients []*clientv3.Client + testMutexTryLock(t, 5, makeSingleNodeClients(t, clus.cluster, &clients)) + closeClients(t, clients) +} + +func TestMutexTryLockMultiNode(t *testing.T) { + clus := NewClusterV3(t, &ClusterConfig{Size: 3}) + defer clus.Terminate(t) + + var clients []*clientv3.Client + testMutexTryLock(t, 5, makeMultiNodeClients(t, clus.cluster, &clients)) + closeClients(t, clients) +} + +func testMutexTryLock(t *testing.T, lockers int, chooseClient func() *clientv3.Client) { + lockedC := make(chan *concurrency.Mutex) + notlockedC := make(chan *concurrency.Mutex) + for i := 0; i < lockers; i++ { + go func() { + session, err := concurrency.NewSession(chooseClient()) + if err != nil { + t.Error(err) + } + m := concurrency.NewMutex(session, "test-mutex-try-lock") + err = m.TryLock(context.TODO()) + if err == nil { + lockedC <- m + } else if err == concurrency.ErrLocked { + notlockedC <- m + } else { + t.Errorf("Unexpected Error %v", err) + } + }() + } + + timerC := time.After(time.Second) + select { + case <-lockedC: + for i := 0; i < lockers-1; i++ { + select { + case <-lockedC: + t.Fatalf("Multiple Mutes locked on same key") + case <-notlockedC: + case <-timerC: + t.Errorf("timed out waiting for lock") + } + } + case <-timerC: + t.Errorf("timed out waiting for lock") + } +} + // TestMutexSessionRelock ensures that acquiring the same lock with the same // session will not result in deadlock. func TestMutexSessionRelock(t *testing.T) { @@ -219,7 +275,7 @@ func BenchmarkMutex4Waiters(b *testing.B) { clus := NewClusterV3(nil, &ClusterConfig{Size: 3}) defer clus.Terminate(nil) for i := 0; i < b.N; i++ { - testMutex(nil, 4, func() *clientv3.Client { return clus.RandClient() }) + testMutexLock(nil, 4, func() *clientv3.Client { return clus.RandClient() }) } } From c9d00ce1303dbe88431727a6f6a77682767881a9 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 10 Sep 2019 10:43:06 -0700 Subject: [PATCH 03/33] README: require 1.13 Signed-off-by: Gyuho Lee --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 655d31408..980c304a2 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ The easiest way to get etcd is to use one of the pre-built release binaries whic For more installation guides, please check out [play.etcd.io](http://play.etcd.io) and [operating etcd](https://github.com/etcd-io/etcd/tree/master/Documentation#operating-etcd-clusters). -For those wanting to try the very latest version, [build the latest version of etcd][dl-build] from the `master` branch. This first needs [*Go*](https://golang.org/) installed (version 1.12+ is required). All development occurs on `master`, including new features and bug fixes. Bug fixes are first targeted at `master` and subsequently ported to release branches, as described in the [branch management][branch-management] guide. +For those wanting to try the very latest version, [build the latest version of etcd][dl-build] from the `master` branch. This first needs [*Go*](https://golang.org/) installed (version 1.13+ is required). All development occurs on `master`, including new features and bug fixes. Bug fixes are first targeted at `master` and subsequently ported to release branches, as described in the [branch management][branch-management] guide. [github-release]: https://github.com/etcd-io/etcd/releases [branch-management]: ./Documentation/branch_management.md From 2ed05bfc335febfdf82d57614cfb89f05cf73b42 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 11 Sep 2019 12:25:49 -0700 Subject: [PATCH 04/33] vendor: upgrade to gRPC v1.23.1 https://github.com/grpc/grpc-go/releases/tag/v1.23.1 Signed-off-by: Gyuho Lee --- go.mod | 2 +- go.sum | 4 ++-- .../grpc/internal/transport/http2_server.go | 5 ++++- .../google.golang.org/grpc/internal/transport/http_util.go | 1 + vendor/google.golang.org/grpc/version.go | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 67e5eb397..fae97d320 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 // indirect golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 - google.golang.org/grpc v1.23.0 + google.golang.org/grpc v1.23.1 gopkg.in/cheggaaa/pb.v1 v1.0.25 gopkg.in/yaml.v2 v2.2.2 sigs.k8s.io/yaml v1.1.0 diff --git a/go.sum b/go.sum index 8122801c6..a610e71bd 100644 --- a/go.sum +++ b/go.sum @@ -181,8 +181,8 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index 83439b562..4e26f6a1d 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -138,7 +138,10 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err } framer := newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize) // Send initial settings as connection preface to client. - var isettings []http2.Setting + isettings := []http2.Setting{{ + ID: http2.SettingMaxFrameSize, + Val: http2MaxFrameLen, + }} // TODO(zhaoq): Have a better way to signal "no limit" because 0 is // permitted in the HTTP2 spec. maxStreams := config.MaxStreams diff --git a/vendor/google.golang.org/grpc/internal/transport/http_util.go b/vendor/google.golang.org/grpc/internal/transport/http_util.go index 9d212867c..8f5f3349d 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http_util.go +++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -667,6 +667,7 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderList writer: w, fr: http2.NewFramer(w, r), } + f.fr.SetMaxReadFrameSize(http2MaxFrameLen) // Opt-in to Frame reuse API on framer to reduce garbage. // Frames aren't safe to read from after a subsequent call to ReadFrame. f.fr.SetReuseFrames() diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 5411a73a2..588850563 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.23.0" +const Version = "1.23.1" From 2822da86590c00e701cf73eec323ae42f8495992 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 11 Sep 2019 14:56:18 -0700 Subject: [PATCH 05/33] CHANGELOG: update gRPC Dependency changes Signed-off-by: Gyuho Lee --- CHANGELOG-3.2.md | 1 + CHANGELOG-3.4.md | 4 ++++ CHANGELOG-3.5.md | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/CHANGELOG-3.2.md b/CHANGELOG-3.2.md index ed8f6811e..a46570232 100644 --- a/CHANGELOG-3.2.md +++ b/CHANGELOG-3.2.md @@ -30,6 +30,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Add [`etcd_debugging_mvcc_current_revision`](https://github.com/etcd-io/etcd/pull/11126) Prometheus metric. - Add [`etcd_debugging_mvcc_compact_revision`](https://github.com/etcd-io/etcd/pull/11126) Prometheus metric. +
diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 5b2e3daca..9ebdad9f5 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -29,6 +29,10 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Fix [secure server logging message](https://github.com/etcd-io/etcd/commit/8b053b0f44c14ac0d9f39b9b78c17c57d47966eb). - Remove [redundant `%` characters in file descriptor warning message](https://github.com/etcd-io/etcd/commit/d5f79adc9cea9ec8c93669526464b0aa19ed417b). +### Dependency + +- Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) from [**`v1.23.0`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.0) to [**`v1.23.1`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.1). + ### Go - Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes. diff --git a/CHANGELOG-3.5.md b/CHANGELOG-3.5.md index 4a8ac0776..b2a9e576d 100644 --- a/CHANGELOG-3.5.md +++ b/CHANGELOG-3.5.md @@ -87,6 +87,10 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Deprecated [`/v3beta`](https://github.com/etcd-io/etcd/pull/9298). - `curl -L http://localhost:2379/v3beta/kv/put -X POST -d '{"key": "Zm9v", "value": "YmFy"}'` does work in v3.5. Use `curl -L http://localhost:2379/v3/kv/put -X POST -d '{"key": "Zm9v", "value": "YmFy"}'` instead. +### Dependency + +- Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) from [**`v1.23.0`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.0) to [**`v1.23.1`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.1). + ### Go - Require [*Go 1.13+*](https://github.com/etcd-io/etcd/pull/11110). From 82e3579250906eaf164fcee8d46873bbf8792e1a Mon Sep 17 00:00:00 2001 From: Vimal K Date: Thu, 12 Sep 2019 14:34:26 -0700 Subject: [PATCH 06/33] *: Update CHANGELOG-3.5.md for Mutex.TryLock Added https://github.com/etcd-io/etcd/pull/11104 to CHANGELOG for 3.5 --- CHANGELOG-3.5.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG-3.5.md b/CHANGELOG-3.5.md index b2a9e576d..a77536ffc 100644 --- a/CHANGELOG-3.5.md +++ b/CHANGELOG-3.5.md @@ -81,6 +81,11 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Remove [`embed.Config.Debug`](https://github.com/etcd-io/etcd/pull/10947). - Use `embed.Config.LogLevel` instead. +### Package `clientv3` + +- Add [TryLock](https://github.com/etcd-io/etcd/pull/11104) method to `clientv3/concurrency/Mutex`. A non-blocking method on `Mutex` which does not wait to get lock on the Mutex, returns immediately if Mutex is locked by another session. + + ### gRPC gateway - [gRPC gateway](https://github.com/grpc-ecosystem/grpc-gateway) only supports [`/v3`](TODO) endpoint. From e8660c0ceca6eecee472e6d5fd0583f6a3d406b8 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 13 Sep 2019 07:46:01 -0400 Subject: [PATCH 07/33] embed: expose ZapLoggerBuilder This exposes the ZapLoggerBuilder in the embed.Config to allow for custom loggers to be defined and used by embedded etcd. Fixes #11144 --- embed/config.go | 4 ++-- embed/config_logging.go | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/embed/config.go b/embed/config.go index 278316b51..2f64d927f 100644 --- a/embed/config.go +++ b/embed/config.go @@ -303,8 +303,8 @@ type Config struct { // It can be multiple when "Logger" is zap. LogOutputs []string `json:"log-outputs"` - // zapLoggerBuilder is used to build the zap logger. - zapLoggerBuilder func(*Config) error + // ZapLoggerBuilder is used to build the zap logger. + ZapLoggerBuilder func(*Config) error // logger logs server-side operations. The default is nil, // and "setupLogging" must be called before starting server. diff --git a/embed/config_logging.go b/embed/config_logging.go index 583f343d1..e42103cb1 100644 --- a/embed/config_logging.go +++ b/embed/config_logging.go @@ -181,8 +181,8 @@ func (cfg *Config) setupLogging() error { // TODO: remove "Debug" check in v3.5 grpc.EnableTracing = true } - if cfg.zapLoggerBuilder == nil { - cfg.zapLoggerBuilder = func(c *Config) error { + if cfg.ZapLoggerBuilder == nil { + cfg.ZapLoggerBuilder = func(c *Config) error { var err error c.logger, err = copied.Build() if err != nil { @@ -235,8 +235,8 @@ func (cfg *Config) setupLogging() error { syncer, lvl, ) - if cfg.zapLoggerBuilder == nil { - cfg.zapLoggerBuilder = func(c *Config) error { + if cfg.ZapLoggerBuilder == nil { + cfg.ZapLoggerBuilder = func(c *Config) error { c.logger = zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer)) c.loggerMu.Lock() defer c.loggerMu.Unlock() @@ -252,7 +252,7 @@ func (cfg *Config) setupLogging() error { } } - err := cfg.zapLoggerBuilder(cfg) + err := cfg.ZapLoggerBuilder(cfg) if err != nil { return err } From b4be60515b43b2fb8c108fd3f74c54dc0b2f79d2 Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Fri, 13 Sep 2019 15:51:46 -0400 Subject: [PATCH 08/33] CHANGELOG: update 3.4.1 and 3.5 Update from #11147 and #11148 --- CHANGELOG-3.4.md | 4 ++++ CHANGELOG-3.5.md | 1 + 2 files changed, 5 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 9ebdad9f5..7da2bb38a 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -37,6 +37,10 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes. +### Package `embed` + +- Add [`embed.Config.ZapLoggerBuilder`](https://github.com/etcd-io/etcd/pull/11148) to allow creating a custom zap logger. +
diff --git a/CHANGELOG-3.5.md b/CHANGELOG-3.5.md index a77536ffc..e9f815e12 100644 --- a/CHANGELOG-3.5.md +++ b/CHANGELOG-3.5.md @@ -80,6 +80,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Remove [`embed.Config.Debug`](https://github.com/etcd-io/etcd/pull/10947). - Use `embed.Config.LogLevel` instead. +- Add [`embed.Config.ZapLoggerBuilder`](https://github.com/etcd-io/etcd/pull/11147) to allow creating a custom zap logger. ### Package `clientv3` From 0dd10cf6b8e1643b65cd9931777491137225c1fa Mon Sep 17 00:00:00 2001 From: Debabrata Banerjee Date: Fri, 9 Aug 2019 11:45:20 -0400 Subject: [PATCH 09/33] etcdserver: Fix PeerURL validation In case of URLs that are synonyms, the current lexicographic sorting and compare of the URLs fails with frustrating errors. Make sure to do a full comparison between every set of PeerURLs before failing. Fixes #11013 --- etcdserver/api/membership/cluster.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/etcdserver/api/membership/cluster.go b/etcdserver/api/membership/cluster.go index 81f515d2f..89a6edd25 100644 --- a/etcdserver/api/membership/cluster.go +++ b/etcdserver/api/membership/cluster.go @@ -759,16 +759,21 @@ func ValidateClusterAndAssignIDs(lg *zap.Logger, local *RaftCluster, existing *R if len(ems) != len(lms) { return fmt.Errorf("member count is unequal") } - sort.Sort(MembersByPeerURLs(ems)) - sort.Sort(MembersByPeerURLs(lms)) ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) defer cancel() for i := range ems { - if ok, err := netutil.URLStringsEqual(ctx, lg, ems[i].PeerURLs, lms[i].PeerURLs); !ok { - return fmt.Errorf("unmatched member while checking PeerURLs (%v)", err) + var err error + ok := false + for j := range lms { + if ok, err = netutil.URLStringsEqual(ctx, lg, ems[i].PeerURLs, lms[j].PeerURLs); ok { + lms[j].ID = ems[i].ID + break + } + } + if !ok { + return fmt.Errorf("PeerURLs: no match found for existing member (%v, %v), last resolver error (%v)", ems[i].ID, ems[i].PeerURLs, err) } - lms[i].ID = ems[i].ID } local.members = make(map[types.ID]*Member) for _, m := range lms { From e4cb346c3ae8388656165842a1d28ad361caaf1c Mon Sep 17 00:00:00 2001 From: Vimal K Date: Sat, 14 Sep 2019 13:57:55 -0700 Subject: [PATCH 10/33] travis: re-enable bom tests bill-of-materials was fixed for module aware 'go list' as part of https://github.com/coreos/license-bill-of-materials/pull/17 So can re enable bom tests fixes #11132 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4a467bc6d..ed0b0ec3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -75,7 +75,7 @@ script: linux-amd64-fmt) docker run --rm \ --volume=`pwd`:/go/src/go.etcd.io/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \ - /bin/bash -c "GOARCH=amd64 PASSES='fmt dep' ./test" + /bin/bash -c "GOARCH=amd64 PASSES='fmt bom dep' ./test" ;; linux-amd64-integration-1-cpu) docker run --rm \ From 78fb1e34f882674d6ce5327c78c09f7e133aaf25 Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Sun, 15 Sep 2019 17:48:04 -0400 Subject: [PATCH 11/33] hack: fix cherrypick instruction Remotes is not a valid git command. Also, set the environmental variable correctly. --- hack/patch/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hack/patch/README.md b/hack/patch/README.md index 07c22e62b..39e1a4d8b 100644 --- a/hack/patch/README.md +++ b/hack/patch/README.md @@ -7,14 +7,14 @@ Handles cherry-picks of PR(s) from etcd master to a stable etcd release branch a Set the `UPSTREAM_REMOTE` and `FORK_REMOTE` environment variables. `UPSTREAM_REMOTE` should be set to git remote name of `github.com/etcd-io/etcd`, and `FORK_REMOTE` should be set to the git remote name of the forked etcd -repo (`github.com/${github-username}/etcd`). Use `git remotes -v` to +repo (`github.com/${github-username}/etcd`). Use `git remote -v` to look up the git remote names. If etcd has not been forked, create one on github.com and register it locally with `git remote add ...`. ``` -export UPSTREAM_REMOTE=origin -export FORK_REMOTE=${github-username} +export UPSTREAM_REMOTE=upstream +export FORK_REMOTE=origin export GITHUB_USER=${github-username} ``` From 6287052bd083358a508a456d953a2a6f55657903 Mon Sep 17 00:00:00 2001 From: Guangming Wang Date: Mon, 16 Sep 2019 13:22:44 +0800 Subject: [PATCH 12/33] integration: fix bug in for loop, make it break properly --- clientv3/integration/cluster_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clientv3/integration/cluster_test.go b/clientv3/integration/cluster_test.go index a5cf5d51a..0961c55d7 100644 --- a/clientv3/integration/cluster_test.go +++ b/clientv3/integration/cluster_test.go @@ -276,8 +276,7 @@ func TestMemberPromote(t *testing.T) { select { case <-time.After(500 * time.Millisecond): case <-timeout: - t.Errorf("failed all attempts to promote learner member, last error: %v", err) - break + t.Fatalf("failed all attempts to promote learner member, last error: %v", err) } _, err = capi.MemberPromote(context.Background(), learnerID) From 2530c900fd30b9704816b44d517e572c84e733f3 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 17 Sep 2019 13:29:30 -0700 Subject: [PATCH 13/33] CHANGELOG: update with patch release Signed-off-by: Gyuho Lee --- CHANGELOG-3.1.md | 2 +- CHANGELOG-3.2.md | 15 +++++++++++++-- CHANGELOG-3.3.md | 25 ++++++++++++++++--------- CHANGELOG-3.4.md | 10 +++++----- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md index a8180b96f..f4562b9cb 100644 --- a/CHANGELOG-3.1.md +++ b/CHANGELOG-3.1.md @@ -10,7 +10,7 @@ The minimum recommended etcd versions to run in **production** are 3.1.11+, 3.2. ## [v3.1.21](https://github.com/etcd-io/etcd/releases/tag/v3.1.21) (2019-TBD) -### etcdctl +### etcdctl v3 - [Strip out insecure endpoints from DNS SRV records when using discovery](https://github.com/etcd-io/etcd/pull/10443) with etcdctl v2 - Add [`etcdctl endpoint health --write-out` support](https://github.com/etcd-io/etcd/pull/9540). diff --git a/CHANGELOG-3.2.md b/CHANGELOG-3.2.md index a46570232..3655e200c 100644 --- a/CHANGELOG-3.2.md +++ b/CHANGELOG-3.2.md @@ -9,9 +9,9 @@ The minimum recommended etcd versions to run in **production** are 3.1.11+, 3.2.
-## [v3.2.27](https://github.com/etcd-io/etcd/releases/tag/v3.2.27) (2019-TBD) +## [v3.2.27](https://github.com/etcd-io/etcd/releases/tag/v3.2.27) (2019-09-17) -### etcdctl +### etcdctl v3 - [Strip out insecure endpoints from DNS SRV records when using discovery](https://github.com/etcd-io/etcd/pull/10443) with etcdctl v2 - Add [`etcdctl endpoint health --write-out` support](https://github.com/etcd-io/etcd/pull/9540). @@ -19,6 +19,13 @@ The minimum recommended etcd versions to run in **production** are 3.1.11+, 3.2. - The command output is changed. Previously, if endpoint is unreachable, the command output is "\ is unhealthy: failed to connect: \". This change unified the error message, all error types now have the same output "\ is unhealthy: failed to commit proposal: \". +- Fix [`etcdctl snapshot status` to not modify snapshot file](https://github.com/etcd-io/etcd/pull/11157). + - For example, start etcd `v3.3.10` + - Write some data + - Use etcdctl `v3.3.10` to save snapshot + - Somehow, upgrading Kubernetes fails, thus rolling back to previous version etcd `v3.2.24` + - Run etcdctl `v3.2.24` `snapshot status` against the snapshot file saved from `v3.3.10` server + - Run etcdctl `v3.2.24` `snapshot restore` fails with `"expected sha256 [12..."` ### Metrics, Monitoring @@ -30,6 +37,10 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Add [`etcd_debugging_mvcc_current_revision`](https://github.com/etcd-io/etcd/pull/11126) Prometheus metric. - Add [`etcd_debugging_mvcc_compact_revision`](https://github.com/etcd-io/etcd/pull/11126) Prometheus metric. +### Go + +- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8). +
diff --git a/CHANGELOG-3.3.md b/CHANGELOG-3.3.md index 19f6c19c5..efdfe34a7 100644 --- a/CHANGELOG-3.3.md +++ b/CHANGELOG-3.3.md @@ -15,14 +15,6 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.15...v3.3.16) an **Again, before running upgrades from any previous release, please make sure to read change logs below and [v3.3 upgrade guide](https://github.com/etcd-io/etcd/blob/master/Documentation/upgrades/upgrade_3_3.md).** -### Dependency - -- Upgrade [`github.com/coreos/bbolt`](https://github.com/etcd-io/bbolt/releases) from [**`v1.3.1-coreos.6`**](https://github.com/etcd-io/bbolt/releases/tag/v1.3.1-coreos.6) to [**`v1.3.3`**](https://github.com/etcd-io/bbolt/releases/tag/v1.3.3). - -### Go - -- Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes. - ### Metrics, Monitoring See [List of metrics](https://github.com/etcd-io/etcd/tree/master/Documentation/metrics) for all metrics per release. @@ -32,6 +24,14 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Add [`etcd_debugging_mvcc_current_revision`](https://github.com/etcd-io/etcd/pull/11126) Prometheus metric. - Add [`etcd_debugging_mvcc_compact_revision`](https://github.com/etcd-io/etcd/pull/11126) Prometheus metric. +### Dependency + +- Upgrade [`github.com/coreos/bbolt`](https://github.com/etcd-io/bbolt/releases) from [**`v1.3.1-coreos.6`**](https://github.com/etcd-io/bbolt/releases/tag/v1.3.1-coreos.6) to [**`v1.3.3`**](https://github.com/etcd-io/bbolt/releases/tag/v1.3.3). + +### Go + +- Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes. +
@@ -208,7 +208,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.11...v3.3.12) an **Again, before running upgrades from any previous release, please make sure to read change logs below and [v3.3 upgrade guide](https://github.com/etcd-io/etcd/blob/master/Documentation/upgrades/upgrade_3_3.md).** -### etcdctl +### etcdctl v3 - [Strip out insecure endpoints from DNS SRV records when using discovery](https://github.com/etcd-io/etcd/pull/10443) with etcdctl v2 @@ -772,6 +772,13 @@ See [security doc](https://github.com/etcd-io/etcd/blob/master/Documentation/op- - Enable [`clientv3.WithRequireLeader(context.Context)` for `watch`](https://github.com/etcd-io/etcd/pull/8672) command. - Print [`"del"` instead of `"delete"`](https://github.com/etcd-io/etcd/pull/8297) in `txn` interactive mode. - Print [`ETCD_INITIAL_ADVERTISE_PEER_URLS` in `member add`](https://github.com/etcd-io/etcd/pull/8332). +- Fix [`etcdctl snapshot status` to not modify snapshot file](https://github.com/etcd-io/etcd/pull/8815). + - For example, start etcd `v3.3.10` + - Write some data + - Use etcdctl `v3.3.10` to save snapshot + - Somehow, upgrading Kubernetes fails, thus rolling back to previous version etcd `v3.2.24` + - Run etcdctl `v3.2.24` `snapshot status` against the snapshot file saved from `v3.3.10` server + - Run etcdctl `v3.2.24` `snapshot restore` fails with `"expected sha256 [12..."` ### etcdctl v3 diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 7da2bb38a..bf3d3d79f 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -9,7 +9,7 @@ The minimum recommended etcd versions to run in **production** are 3.1.11+, 3.2.
-## [v3.4.1](https://github.com/etcd-io/etcd/releases/tag/v3.4.1) (2019-TBD) +## [v3.4.1](https://github.com/etcd-io/etcd/releases/tag/v3.4.1) (2019-09-17) See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.0...v3.4.1) and [v3.4 upgrade guide](https://github.com/etcd-io/etcd/blob/master/Documentation/upgrades/upgrade_3_4.md) for any breaking changes. @@ -29,6 +29,10 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Fix [secure server logging message](https://github.com/etcd-io/etcd/commit/8b053b0f44c14ac0d9f39b9b78c17c57d47966eb). - Remove [redundant `%` characters in file descriptor warning message](https://github.com/etcd-io/etcd/commit/d5f79adc9cea9ec8c93669526464b0aa19ed417b). +### Package `embed` + +- Add [`embed.Config.ZapLoggerBuilder`](https://github.com/etcd-io/etcd/pull/11148) to allow creating a custom zap logger. + ### Dependency - Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) from [**`v1.23.0`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.0) to [**`v1.23.1`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.1). @@ -37,10 +41,6 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes. -### Package `embed` - -- Add [`embed.Config.ZapLoggerBuilder`](https://github.com/etcd-io/etcd/pull/11148) to allow creating a custom zap logger. -
From c327120ba025cc31f29375041089bce57e84e752 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 17 Sep 2019 13:52:22 -0700 Subject: [PATCH 14/33] scripts/release: fix docker push command Signed-off-by: Gyuho Lee --- scripts/release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release b/scripts/release index 5e8d768ba..62c8d500f 100755 --- a/scripts/release +++ b/scripts/release @@ -185,7 +185,7 @@ main() { docker push "quay.io/coreos/etcd:${RELEASE_VERSION}" echo "Pushing container images to gcr.io ${RELEASE_VERSION}" - gcloud docker -- "push gcr.io/etcd-development/etcd:${RELEASE_VERSION}" + gcloud docker -- push "gcr.io/etcd-development/etcd:${RELEASE_VERSION}" for TARGET_ARCH in "-arm64" "-ppc64le"; do echo "Pushing container images to quay.io ${RELEASE_VERSION}${TARGET_ARCH}" From 838315283d9e7ab58d83482bf9bab2e88a4707e4 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 17 Sep 2019 14:12:18 -0700 Subject: [PATCH 15/33] scripts/release: fix SHA256SUMS command Signed-off-by: Gyuho Lee --- scripts/release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release b/scripts/release index 62c8d500f..376d6f42f 100755 --- a/scripts/release +++ b/scripts/release @@ -147,7 +147,7 @@ main() { # Generate SHA256SUMS echo -e "Generating sha256sums of release artifacts.\n" pushd ./release - grep . -E '\.tar.gz$|\.zip$' | xargs shasum -a 256 > ./SHA256SUMS + ls . | grep -E '\.tar.gz$|\.zip$' | xargs shasum -a 256 > ./SHA256SUMS popd if [ -s ./release/SHA256SUMS ]; then cat ./release/SHA256SUMS From e53298afb1672a1c02ea1c9606546f2ea7247b72 Mon Sep 17 00:00:00 2001 From: Jingguo Yao Date: Wed, 18 Sep 2019 16:37:25 +0800 Subject: [PATCH 16/33] clientv3/concurrency: remove the unneeded slash Since NewMutex will append a slash to pfx, there is no need to append a slash beforehand. --- clientv3/concurrency/example_mutex_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clientv3/concurrency/example_mutex_test.go b/clientv3/concurrency/example_mutex_test.go index 6b55340cf..d2c2cea80 100644 --- a/clientv3/concurrency/example_mutex_test.go +++ b/clientv3/concurrency/example_mutex_test.go @@ -36,14 +36,14 @@ func ExampleMutex_TryLock() { log.Fatal(err) } defer s1.Close() - m1 := concurrency.NewMutex(s1, "/my-lock/") + m1 := concurrency.NewMutex(s1, "/my-lock") s2, err := concurrency.NewSession(cli) if err != nil { log.Fatal(err) } defer s2.Close() - m2 := concurrency.NewMutex(s2, "/my-lock/") + m2 := concurrency.NewMutex(s2, "/my-lock") // acquire lock for s1 if err = m1.Lock(context.TODO()); err != nil { From e24564224a1eae633c6ed4c0f6b1bdc8a8eebfd8 Mon Sep 17 00:00:00 2001 From: Jingguo Yao Date: Wed, 18 Sep 2019 23:06:14 +0800 Subject: [PATCH 17/33] clientv3: remove the redundant CancelFunc invocation --- clientv3/example_kv_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/clientv3/example_kv_test.go b/clientv3/example_kv_test.go index ae552583a..c3f348b3e 100644 --- a/clientv3/example_kv_test.go +++ b/clientv3/example_kv_test.go @@ -249,7 +249,6 @@ func ExampleKV_txn() { } gresp, err := kvc.Get(context.TODO(), "key") - cancel() if err != nil { log.Fatal(err) } From 5370570fec7f6e14c1f2ef5689dd45b67f34895c Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Wed, 18 Sep 2019 14:09:18 -0400 Subject: [PATCH 18/33] *: update project code of conduct Update the code of conduct. Remove notice file. --- NOTICE | 5 ---- code-of-conduct.md | 62 ++-------------------------------------------- 2 files changed, 2 insertions(+), 65 deletions(-) delete mode 100644 NOTICE diff --git a/NOTICE b/NOTICE deleted file mode 100644 index b39ddfa5c..000000000 --- a/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -CoreOS Project -Copyright 2014 CoreOS, Inc - -This product includes software developed at CoreOS, Inc. -(http://www.coreos.com/). diff --git a/code-of-conduct.md b/code-of-conduct.md index a234f3609..d79cc5488 100644 --- a/code-of-conduct.md +++ b/code-of-conduct.md @@ -1,61 +1,3 @@ -## CoreOS Community Code of Conduct +## etcd Community Code of Conduct -### Contributor Code of Conduct - -As contributors and maintainers of this project, and in the interest of -fostering an open and welcoming community, we pledge to respect all people who -contribute through reporting issues, posting feature requests, updating -documentation, submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free -experience for everyone, regardless of level of experience, gender, gender -identity and expression, sexual orientation, disability, personal appearance, -body size, race, ethnicity, age, religion, or nationality. - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing others' private information, such as physical or electronic addresses, without explicit permission -* Other unethical or unprofessional conduct. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct. By adopting this Code of Conduct, -project maintainers commit themselves to fairly and consistently applying these -principles to every aspect of managing this project. Project maintainers who do -not follow or enforce the Code of Conduct may be permanently removed from the -project team. - -This code of conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting a project maintainer, Brandon Philips -, and/or Rithu John . - -This Code of Conduct is adapted from the Contributor Covenant -(http://contributor-covenant.org), version 1.2.0, available at -http://contributor-covenant.org/version/1/2/0/ - -### CoreOS Events Code of Conduct - -CoreOS events are working conferences intended for professional networking and -collaboration in the CoreOS community. Attendees are expected to behave -according to professional standards and in accordance with their employer’s -policies on appropriate workplace behavior. - -While at CoreOS events or related social networking opportunities, attendees -should not engage in discriminatory or offensive speech or actions including -but not limited to gender, sexuality, race, age, disability, or religion. -Speakers should be especially aware of these concerns. - -CoreOS does not condone any statements by speakers contrary to these standards. -CoreOS reserves the right to deny entrance and/or eject from an event (without -refund) any individual found to be engaging in discriminatory or offensive -speech or actions. - -Please bring any concerns to the immediate attention of designated on-site -staff, Brandon Philips , and/or Rithu John . +etcd follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). From 2c95b49b63651ae3e0a3f63c45c05295d1af2c42 Mon Sep 17 00:00:00 2001 From: lsytj0413 <511121939@qq.com> Date: Thu, 19 Sep 2019 09:51:51 +0800 Subject: [PATCH 19/33] test(functional): remove unknown field Etcd.Debug --- functional/tester/cluster_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/functional/tester/cluster_test.go b/functional/tester/cluster_test.go index 7c7b25f2a..2948c00e7 100644 --- a/functional/tester/cluster_test.go +++ b/functional/tester/cluster_test.go @@ -64,7 +64,6 @@ func Test_read(t *testing.T) { InitialCorruptCheck: true, Logger: "zap", LogOutputs: []string{"/tmp/etcd-functional-1/etcd.log"}, - Debug: true, }, ClientCertData: "", ClientCertPath: "", @@ -117,7 +116,6 @@ func Test_read(t *testing.T) { InitialCorruptCheck: true, Logger: "zap", LogOutputs: []string{"/tmp/etcd-functional-2/etcd.log"}, - Debug: true, }, ClientCertData: "", ClientCertPath: "", @@ -170,7 +168,6 @@ func Test_read(t *testing.T) { InitialCorruptCheck: true, Logger: "zap", LogOutputs: []string{"/tmp/etcd-functional-3/etcd.log"}, - Debug: true, }, ClientCertData: "", ClientCertPath: "", From 129138760cbb79bc183abf6652455d27d6748818 Mon Sep 17 00:00:00 2001 From: Wenjia Date: Thu, 19 Sep 2019 11:55:43 -0700 Subject: [PATCH 20/33] Update README.md with 9/19/2019 meeting recording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 980c304a2..0c445603e 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Time: - [Jul 11th, 2019 11:00 AM video](https://youtu.be/k_FZEipWD6Y) - [Jul 25, 2019 11:00 AM video](https://youtu.be/VSUJTACO93I) - [Aug 22, 2019 11:00 AM video](https://youtu.be/6IBQ-VxQmuM) -- Sep 19, 2019 11:00 AM +- [Sep 19, 2019 11:00 AM video](https://youtu.be/SqfxU9DhBOc) - Nov 14, 2019 11:00 AM - Dec 12, 2019 11:00 AM From 4681061b1fb3cda0c9de82999bb9391de8e27371 Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Sun, 22 Sep 2019 16:12:31 -0400 Subject: [PATCH 21/33] *: add slack contact Add slack chat contact. --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9bcc0b1a5..deb1b9101 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,6 +6,7 @@ etcd is Apache 2.0 licensed and accepts contributions via GitHub pull requests. - Email: [etcd-dev](https://groups.google.com/forum/?hl=en#!forum/etcd-dev) - IRC: #[etcd](irc://irc.freenode.org:6667/#etcd) IRC channel on freenode.org +- Slack: [#etcd](https://kubernetes.slack.com/messages/C3HD8ARJ5/details/) ## Getting started From 7cb2bb67bfc75feed2bc8a78cdbbf05a6c2dbf47 Mon Sep 17 00:00:00 2001 From: Yahya <5457202+anakaiti@users.noreply.github.com> Date: Mon, 23 Sep 2019 22:19:37 +0700 Subject: [PATCH 22/33] README: fix formatting on hangouts link Added link and removed wrongly copied text --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0c445603e..a51169807 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,9 @@ Time: - Nov 14, 2019 11:00 AM - Dec 12, 2019 11:00 AM -Join Hangouts Meet -meet.google.com/umg-nrxn-qvs +Join Hangouts Meet: [meet.google.com/umg-nrxn-qvs](https://meet.google.com/umg-nrxn-qvs) -Join by phone -‪+1 405-792-0633‬ PIN: ‪299 906‬# -More phone numbers +Join by phone: +1 405-792-0633‬ PIN: ‪299 906‬# ## Getting started From 06ec6c4b660ca0ddcaa3455a87024fb95ca292f5 Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Mon, 23 Sep 2019 16:18:53 -0400 Subject: [PATCH 23/33] *: create project governance Create project governance. --- GOVERNANCE.md | 88 ++++++++++++++++++++++++++++++++++++++++++++ MAINTAINERS | 11 +++++- MAINTAINERS_RULES.md | 16 -------- OWNERS | 20 ---------- 4 files changed, 98 insertions(+), 37 deletions(-) create mode 100644 GOVERNANCE.md delete mode 100644 MAINTAINERS_RULES.md delete mode 100644 OWNERS diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 000000000..b7d10081f --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,88 @@ +# etcd Governance + +## Principles + +The etcd community adheres to the following principles: + +- Open: etcd is open source. +- Welcoming and respectful: See [Code of Conduct](code-of-conduct.md). +- Transparent and accessible: Changes to the etcd code repository and CNCF related +activities (e.g. level, involvement, etc) are done in public. +- Merit: Ideas and contributions are accepted according to their technical merit for +the betterment of the project. For specific guidance on practical contribution steps +please see [CONTRIBUTING](./CONTRIBUTING.md) guide. + +## Maintainers + +[Maintainers](./MAINTAINERS) are first and foremost contributors that have shown they +are committed to the long term success of a project. Maintainership is about building +trust with the current maintainers of the project and being a person that they can +depend on to make decisions in the best interest of the project in a consistent manner. +The maintainers role can be a top-level or restricted to certain package/feature +depending upon their commitment in fulfilling the expected responsibilities as explained +below. + +### Top-level maintainer + +- Running the etcd release processes +- Ownership of test and debug infrastructure +- Triage GitHub issues to keep the issue count low (goal: under 100) +- Regularly review GitHub pull requests across all pkgs +- Providing cross pkg design review +- Monitor email aliases +- Participate when called upon in the [security disclosure and release process](security/README.md) +- General project maintenance + +### Package/feature maintainer + +- Ownership of test and debug failures in a pkg/feature +- Resolution of bugs triaged to a package/feature +- Regularly review pull requests to the pkg subsystem + +Contributors who are interested in becoming a maintainer, if performing these +responsibilities, should discuss their interest with the existing maintainers. New +maintainers must be nominated by an existing maintainer and must be elected by a +supermajority of maintainers. Likewise, maintainers can be removed by a supermajority +of the maintainers and moved to emeritus status. + +Life priorities, interests, and passions can change. If a maintainer needs to step +down, inform other maintainers about this intention, and if possible, help find someone +to pick up the related work. At the very least, ensure the related work can be continued. +Afterward, create a pull request to remove yourself from the [MAINTAINERS](./MAINTAINERS) +file. + +## Approvers + +[Approvers](./MAINTAINERS) are contributors with merge rights. They are active reviewers +and have created significant numbers of PRs in the various code areas to add new features, +fix bugs and improve code. New approvers must be nominated by an existing maintainer +and must be elected by a supermajority of maintainers. Likewise, approvers can be removed +by a supermajority of the maintainers or can resign by notifying the maintainers. + +## Reviewers + +[Reviewers](./MAINTAINERS) are contributors who have demonstrated greater skill in +reviewing the code contribution from other contributors. Their LGTM counts towards +merging a code change into the project. New reviewers must be nominated by an existing +maintainer and must be elected by a supermajority of maintainers. Likewise, reviewers +can be removed by a supermajority of the maintainers or can resign by notifying the +maintainers. + +## Decision making process + +Decisions are built on consensus between maintainers publicly. Proposals and ideas +can either be submitted for agreement via a GitHub issue or PR, or by sending an email +to `etcd-maintainers@googlegroups.com`. + +## Conflict resolution + +In general, we prefer that technical issues and maintainer membership are amicably +worked out between the persons involved. However, any technical dispute that has +reached an impasse with a subset of the community, any contributor may open a GitHub +issue or PR or send an email to `etcd-maintainers@googlegroups.com`. If the +maintainers themselves cannot decide an issue, the issue will be resolved by a +supermajority of the maintainers. + +## Changes in Governance + +Changes in project governance could be initiated by opening a GitHub PR. diff --git a/MAINTAINERS b/MAINTAINERS index 541e03ee5..fd85ff1e2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1,4 +1,6 @@ -# This is the official list of etcd maintainers. +# The official list of maintainers, approvers, and reviewers for the project maintenance. +# +# Refer to the GOVERNANCE.md for description of the roles. # # Names should be added to this file like so: # Individual's name (@GITHUB_HANDLE) pkg:* @@ -6,6 +8,7 @@ # # Please keep the list sorted. +# MAINTAINERS Brandon Philips (@philips) pkg:* Gyuho Lee (@gyuho) pkg:* Hitoshi Mitake (@mitake) pkg:* @@ -18,3 +21,9 @@ Xiang Li (@xiang90) pkg:* Ben Darnell (@bdarnell) pkg:go.etcd.io/etcd/raft Tobias Grieger (@tbg) pkg:go.etcd.io/etcd/raft +# APPROVERS +Anthony Romano (@heyitsanthony) pkg:* +Fanmin Shi (@fanminshi) pkg:* + +# REVIEWERS +Wenjia Zhang (@wenjiaswe) pkg:* diff --git a/MAINTAINERS_RULES.md b/MAINTAINERS_RULES.md deleted file mode 100644 index d39d69fc7..000000000 --- a/MAINTAINERS_RULES.md +++ /dev/null @@ -1,16 +0,0 @@ - -This document describes basic expectations for maintainers. To become a maintainer, start taking on these responsibilities. Consistent contributors then discuss with existing maintainers to become the official [MAINTAINERS](./MAINTAINERS). - -### Top-level maintainer - -- Running the etcd release processes -- Ownership of test and debug infrastructure -- Resolve or redirect issues to keep the issue count low (goal: under 100) -- Regularly review pull requests across all pkgs -- Providing cross pkg design review - -### Package/feature maintainer - -- Ownership of test and debug failures in a pkg/feature -- Resolution of bugs triaged to a package/feature -- Regularly review pull requests to the pkg subsystem diff --git a/OWNERS b/OWNERS deleted file mode 100644 index 410efd095..000000000 --- a/OWNERS +++ /dev/null @@ -1,20 +0,0 @@ -approvers: -- heyitsanthony -- philips -- fanminshi -- gyuho -- mitake -- jpbetz -- xiang90 -- hexfusion -reviewers: -- heyitsanthony -- philips -- fanminshi -- gyuho -- mitake -- jpbetz -- xiang90 -- wenjiaswe -- jingyih -- hexfusion From 20acacdea5333ff8b5ab79e0dc1f47d23d5ee5e1 Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Tue, 24 Sep 2019 15:27:46 -0700 Subject: [PATCH 24/33] doc: clarify metrics flag --- Documentation/op-guide/configuration.md | 2 +- etcdmain/config.go | 2 +- etcdmain/help.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/op-guide/configuration.md b/Documentation/op-guide/configuration.md index 1250b5fe0..87075f2e5 100644 --- a/Documentation/op-guide/configuration.md +++ b/Documentation/op-guide/configuration.md @@ -411,7 +411,7 @@ Follow the instructions when using these flags. + env variable: ETCD_ENABLE_PPROF ### --metrics -+ Set level of detail for exported metrics, specify 'extensive' to include histogram metrics. ++ Set level of detail for exported metrics, specify 'extensive' to include server side grpc histogram metrics. + default: basic + env variable: ETCD_METRICS diff --git a/etcdmain/config.go b/etcdmain/config.go index ac9441854..33d1fd06a 100644 --- a/etcdmain/config.go +++ b/etcdmain/config.go @@ -240,7 +240,7 @@ func newConfig() *config { fs.BoolVar(&cfg.ec.EnablePprof, "enable-pprof", false, "Enable runtime profiling data via HTTP server. Address is at client URL + \"/debug/pprof/\"") // additional metrics - fs.StringVar(&cfg.ec.Metrics, "metrics", cfg.ec.Metrics, "Set level of detail for exported metrics, specify 'extensive' to include histogram metrics") + fs.StringVar(&cfg.ec.Metrics, "metrics", cfg.ec.Metrics, "Set level of detail for exported metrics, specify 'extensive' to include server side grpc histogram metrics") // auth fs.StringVar(&cfg.ec.AuthToken, "auth-token", cfg.ec.AuthToken, "Specify auth token specific options.") diff --git a/etcdmain/help.go b/etcdmain/help.go index 693b8af3a..d30429562 100644 --- a/etcdmain/help.go +++ b/etcdmain/help.go @@ -167,7 +167,7 @@ Profiling and Monitoring: --enable-pprof 'false' Enable runtime profiling data via HTTP server. Address is at client URL + "/debug/pprof/" --metrics 'basic' - Set level of detail for exported metrics, specify 'extensive' to include histogram metrics. + Set level of detail for exported metrics, specify 'extensive' to include server side grpc histogram metrics. --listen-metrics-urls '' List of URLs to listen on for the metrics and health endpoints. From 97388ce4545aba201848661d0ac66a62979582cb Mon Sep 17 00:00:00 2001 From: Joe Betz Date: Tue, 24 Sep 2019 23:55:25 -0700 Subject: [PATCH 25/33] clientv3: Set authority used in cert checks to host of endpoint --- .words | 1 + .../balancer/resolver/endpoint/endpoint.go | 18 ++++++ clientv3/client.go | 25 ++++---- clientv3/credentials/credentials.go | 64 ++++++++++++------- 4 files changed, 72 insertions(+), 36 deletions(-) diff --git a/.words b/.words index ced75fa71..1f6695c8a 100644 --- a/.words +++ b/.words @@ -95,6 +95,7 @@ jitter WithBackoff BackoffLinearWithJitter jitter +WithDialer WithMax ServerStreams BidiStreams diff --git a/clientv3/balancer/resolver/endpoint/endpoint.go b/clientv3/balancer/resolver/endpoint/endpoint.go index 1f32039e3..b840d929c 100644 --- a/clientv3/balancer/resolver/endpoint/endpoint.go +++ b/clientv3/balancer/resolver/endpoint/endpoint.go @@ -16,7 +16,9 @@ package endpoint import ( + "context" "fmt" + "net" "net/url" "strings" "sync" @@ -238,3 +240,19 @@ func ParseHostPort(hostPort string) (host string, port string) { } return host, port } + +// Dialer dials a endpoint using net.Dialer. +// Context cancelation and timeout are supported. +func Dialer(ctx context.Context, dialEp string) (net.Conn, error) { + proto, host, _ := ParseEndpoint(dialEp) + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + } + dialer := &net.Dialer{} + if deadline, ok := ctx.Deadline(); ok { + dialer.Deadline = deadline + } + return dialer.DialContext(ctx, proto, host) +} diff --git a/clientv3/client.go b/clientv3/client.go index d6000a85c..d6c2154c0 100644 --- a/clientv3/client.go +++ b/clientv3/client.go @@ -230,24 +230,17 @@ func (c *Client) dialSetupOpts(creds grpccredentials.TransportCredentials, dopts } opts = append(opts, dopts...) - // Provide a net dialer that supports cancelation and timeout. - f := func(dialEp string, t time.Duration) (net.Conn, error) { - proto, host, _ := endpoint.ParseEndpoint(dialEp) - select { - case <-c.ctx.Done(): - return nil, c.ctx.Err() - default: - } - dialer := &net.Dialer{Timeout: t} - return dialer.DialContext(c.ctx, proto, host) - } - opts = append(opts, grpc.WithDialer(f)) - + dialer := endpoint.Dialer if creds != nil { opts = append(opts, grpc.WithTransportCredentials(creds)) + // gRPC load balancer workaround. See credentials.transportCredential for details. + if credsDialer, ok := creds.(TransportCredentialsWithDialer); ok { + dialer = credsDialer.Dialer + } } else { opts = append(opts, grpc.WithInsecure()) } + opts = append(opts, grpc.WithContextDialer(dialer)) // Interceptor retry and backoff. // TODO: Replace all of clientv3/retry.go with interceptor based retry, or with @@ -663,3 +656,9 @@ func IsConnCanceled(err error) bool { // <= gRPC v1.7.x returns 'errors.New("grpc: the client connection is closing")' return strings.Contains(err.Error(), "grpc: the client connection is closing") } + +// TransportCredentialsWithDialer is for a gRPC load balancer workaround. See credentials.transportCredential for details. +type TransportCredentialsWithDialer interface { + grpccredentials.TransportCredentials + Dialer(ctx context.Context, dialEp string) (net.Conn, error) +} diff --git a/clientv3/credentials/credentials.go b/clientv3/credentials/credentials.go index e6fd75cc3..63389c08b 100644 --- a/clientv3/credentials/credentials.go +++ b/clientv3/credentials/credentials.go @@ -22,6 +22,7 @@ import ( "net" "sync" + "go.etcd.io/etcd/clientv3/balancer/resolver/endpoint" "go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes" grpccredentials "google.golang.org/grpc/credentials" ) @@ -65,38 +66,37 @@ func (b *bundle) NewWithMode(mode string) (grpccredentials.Bundle, error) { } // transportCredential implements "grpccredentials.TransportCredentials" interface. +// transportCredential wraps TransportCredentials to track which +// addresses are dialed for which endpoints, and then sets the authority when checking the endpoint's cert to the +// hostname or IP of the dialed endpoint. +// This is a workaround of a gRPC load balancer issue. gRPC uses the dialed target's service name as the authority when +// checking all endpoint certs, which does not work for etcd servers using their hostname or IP as the Subject Alternative Name +// in their TLS certs. +// To enable, include both WithTransportCredentials(creds) and WithContextDialer(creds.Dialer) +// when dialing. type transportCredential struct { gtc grpccredentials.TransportCredentials + mu sync.Mutex + // addrToEndpoint maps from the connection addresses that are dialed to the hostname or IP of the + // endpoint provided to the dialer when dialing + addrToEndpoint map[string]string } func newTransportCredential(cfg *tls.Config) *transportCredential { return &transportCredential{ - gtc: grpccredentials.NewTLS(cfg), + gtc: grpccredentials.NewTLS(cfg), + addrToEndpoint: map[string]string{}, } } func (tc *transportCredential) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, grpccredentials.AuthInfo, error) { - // Only overwrite when authority is an IP address! - // Let's say, a server runs SRV records on "etcd.local" that resolves - // to "m1.etcd.local", and its SAN field also includes "m1.etcd.local". - // But what if SAN does not include its resolved IP address (e.g. 127.0.0.1)? - // Then, the server should only authenticate using its DNS hostname "m1.etcd.local", - // instead of overwriting it with its IP address. - // And we do not overwrite "localhost" either. Only overwrite IP addresses! - if isIP(authority) { - target := rawConn.RemoteAddr().String() - if authority != target { - // When user dials with "grpc.WithDialer", "grpc.DialContext" "cc.parsedTarget" - // update only happens once. This is problematic, because when TLS is enabled, - // retries happen through "grpc.WithDialer" with static "cc.parsedTarget" from - // the initial dial call. - // If the server authenticates by IP addresses, we want to set a new endpoint as - // a new authority. Otherwise - // "transport: authentication handshake failed: x509: certificate is valid for 127.0.0.1, 192.168.121.180, not 192.168.223.156" - // when the new dial target is "192.168.121.180" whose certificate host name is also "192.168.121.180" - // but client tries to authenticate with previously set "cc.parsedTarget" field "192.168.223.156" - authority = target - } + // Set the authority when checking the endpoint's cert to the hostname or IP of the dialed endpoint + tc.mu.Lock() + dialEp, ok := tc.addrToEndpoint[rawConn.RemoteAddr().String()] + tc.mu.Unlock() + if ok { + _, host, _ := endpoint.ParseEndpoint(dialEp) + authority = host } return tc.gtc.ClientHandshake(ctx, authority, rawConn) } @@ -115,8 +115,15 @@ func (tc *transportCredential) Info() grpccredentials.ProtocolInfo { } func (tc *transportCredential) Clone() grpccredentials.TransportCredentials { + copy := map[string]string{} + tc.mu.Lock() + for k, v := range tc.addrToEndpoint { + copy[k] = v + } + tc.mu.Unlock() return &transportCredential{ - gtc: tc.gtc.Clone(), + gtc: tc.gtc.Clone(), + addrToEndpoint: copy, } } @@ -124,6 +131,17 @@ func (tc *transportCredential) OverrideServerName(serverNameOverride string) err return tc.gtc.OverrideServerName(serverNameOverride) } +func (tc *transportCredential) Dialer(ctx context.Context, dialEp string) (net.Conn, error) { + // Keep track of which addresses are dialed for which endpoints + conn, err := endpoint.Dialer(ctx, dialEp) + if conn != nil { + tc.mu.Lock() + tc.addrToEndpoint[conn.RemoteAddr().String()] = dialEp + tc.mu.Unlock() + } + return conn, err +} + // perRPCCredential implements "grpccredentials.PerRPCCredentials" interface. type perRPCCredential struct { authToken string From 46f3e8349bfc5018e48bac12c12e712ee79a5038 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Fri, 27 Sep 2019 23:35:34 -0700 Subject: [PATCH 26/33] scripts/build-binary: fix darwin tar commands Signed-off-by: Gyuho Lee --- scripts/build-binary | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/build-binary b/scripts/build-binary index 1558d2126..54e921ed5 100755 --- a/scripts/build-binary +++ b/scripts/build-binary @@ -57,6 +57,11 @@ function main { cd release setup_env "${PROJ}" "${VER}" + tarcmd=tar + if [[ $(go env GOOS) == "darwin" ]]; then + tarcmd=gtar + fi + for os in darwin windows linux; do export GOOS=${os} TARGET_ARCHS=("amd64") @@ -78,7 +83,7 @@ function main { package "${TARGET}" "${PROJ}" if [ ${GOOS} == "linux" ]; then - tar cfz "${TARGET}.tar.gz" "${TARGET}" + ${tarcmd} cfz "${TARGET}.tar.gz" "${TARGET}" echo "Wrote release/${TARGET}.tar.gz" else zip -qr "${TARGET}.zip" "${TARGET}" From fce0e23d1bd030de55f3e8a3ec282d5bc1d641ae Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Fri, 27 Sep 2019 23:37:11 -0700 Subject: [PATCH 27/33] *: use Go 1.13.1 Signed-off-by: Gyuho Lee --- .travis.yml | 10 +++++----- Makefile | 6 +++--- functional/scripts/docker-local-agent.sh | 2 +- functional/scripts/docker-local-tester.sh | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed0b0ec3f..f291c87f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ sudo: required services: docker go: - - 1.13 + - 1.13.1 - tip notifications: @@ -30,13 +30,13 @@ env: matrix: fast_finish: true allow_failures: - - go: 1.13 + - go: 1.13.1 env: TARGET=linux-amd64-grpcproxy - - go: 1.13 + - go: 1.13.1 env: TARGET=linux-amd64-coverage - go: tip env: TARGET=linux-amd64-fmt-unit-go-tip - - go: 1.13 + - go: 1.13.1 env: TARGET=linux-386-unit exclude: - go: tip @@ -57,7 +57,7 @@ matrix: env: TARGET=linux-amd64-grpcproxy - go: tip env: TARGET=linux-amd64-coverage - - go: 1.13 + - go: 1.13.1 env: TARGET=linux-amd64-fmt-unit-go-tip - go: tip env: TARGET=linux-386-unit diff --git a/Makefile b/Makefile index 964d698dd..f0f6d975b 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ docker-remove: -GO_VERSION ?= 1.13 +GO_VERSION ?= 1.13.1 ETCD_VERSION ?= $(shell git rev-parse --short HEAD || echo "GitNotFound") TEST_SUFFIX = $(shell date +%s | base64 | head -c 15) @@ -65,11 +65,11 @@ endif # Example: -# GO_VERSION=1.13 make build-docker-test +# GO_VERSION=1.13.1 make build-docker-test # make build-docker-test # # gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io -# GO_VERSION=1.13 make push-docker-test +# GO_VERSION=1.13.1 make push-docker-test # make push-docker-test # # gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com diff --git a/functional/scripts/docker-local-agent.sh b/functional/scripts/docker-local-agent.sh index 6e2b92ac0..6e826b72f 100755 --- a/functional/scripts/docker-local-agent.sh +++ b/functional/scripts/docker-local-agent.sh @@ -13,7 +13,7 @@ if ! [[ "${0}" =~ "scripts/docker-local-agent.sh" ]]; then fi if [[ -z "${GO_VERSION}" ]]; then - GO_VERSION=1.13 + GO_VERSION=1.13.1 fi echo "Running with GO_VERSION:" ${GO_VERSION} diff --git a/functional/scripts/docker-local-tester.sh b/functional/scripts/docker-local-tester.sh index 430a0e230..7123957ab 100755 --- a/functional/scripts/docker-local-tester.sh +++ b/functional/scripts/docker-local-tester.sh @@ -6,7 +6,7 @@ if ! [[ "${0}" =~ "scripts/docker-local-tester.sh" ]]; then fi if [[ -z "${GO_VERSION}" ]]; then - GO_VERSION=1.13 + GO_VERSION=1.13.1 fi echo "Running with GO_VERSION:" ${GO_VERSION} From 3712a5d045603013f2ea97ba0fca4eb7daa3a2e5 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Fri, 27 Sep 2019 23:38:49 -0700 Subject: [PATCH 28/33] CHANGELOG-3.4: update Signed-off-by: Gyuho Lee --- CHANGELOG-3.4.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index bf3d3d79f..b5ff8b2ae 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -9,6 +9,24 @@ The minimum recommended etcd versions to run in **production** are 3.1.11+, 3.2.
+## [v3.4.2](https://github.com/etcd-io/etcd/releases/tag/v3.4.2) (2019 TBD) + +See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.1...v3.4.2) and [v3.4 upgrade guide](https://github.com/etcd-io/etcd/blob/master/Documentation/upgrades/upgrade_3_4.md) for any breaking changes. + +**Again, before running upgrades from any previous release, please make sure to read change logs below and [v3.4 upgrade guide](https://github.com/etcd-io/etcd/blob/master/Documentation/upgrades/upgrade_3_4.md).** + +### Dependency + +- Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) from [**`v1.23.1`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.1) to [**`v1.24.0`**](https://github.com/grpc/grpc-go/releases/tag/v1.24.0). + +### Go + +- Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes. + + +
+ + ## [v3.4.1](https://github.com/etcd-io/etcd/releases/tag/v3.4.1) (2019-09-17) See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.0...v3.4.1) and [v3.4 upgrade guide](https://github.com/etcd-io/etcd/blob/master/Documentation/upgrades/upgrade_3_4.md) for any breaking changes. From 426463c433a46c965eeba01256a1ff92577ba50f Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Mon, 30 Sep 2019 10:43:02 -0700 Subject: [PATCH 29/33] vendor: upgrade gRPC Go to v1.24.0 Picking up some performance improvements and bug fixes. https://github.com/grpc/grpc-go/releases/tag/v1.24.0 Signed-off-by: Gyuho Lee --- go.mod | 2 +- go.sum | 4 +- .../grpc/health/grpc_health_v1/health.pb.go | 96 +++++++++------- .../grpc/internal/transport/controlbuf.go | 12 +- .../grpc/internal/transport/http2_client.go | 105 +++++++++--------- .../grpc/internal/transport/http2_server.go | 30 ++--- .../google.golang.org/grpc/service_config.go | 8 ++ vendor/google.golang.org/grpc/version.go | 2 +- 8 files changed, 142 insertions(+), 117 deletions(-) diff --git a/go.mod b/go.mod index fae97d320..d3f6cc447 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 // indirect golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 - google.golang.org/grpc v1.23.1 + google.golang.org/grpc v1.24.0 gopkg.in/cheggaaa/pb.v1 v1.0.25 gopkg.in/yaml.v2 v2.2.2 sigs.k8s.io/yaml v1.1.0 diff --git a/go.sum b/go.sum index a610e71bd..459345ad8 100644 --- a/go.sum +++ b/go.sum @@ -181,8 +181,8 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go index c2f2c7729..c99e27ae5 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go @@ -1,15 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: grpc/health/v1/health.proto -package grpc_health_v1 // import "google.golang.org/grpc/health/grpc_health_v1" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +package grpc_health_v1 import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. @@ -21,7 +22,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type HealthCheckResponse_ServingStatus int32 @@ -38,6 +39,7 @@ var HealthCheckResponse_ServingStatus_name = map[int32]string{ 2: "NOT_SERVING", 3: "SERVICE_UNKNOWN", } + var HealthCheckResponse_ServingStatus_value = map[string]int32{ "UNKNOWN": 0, "SERVING": 1, @@ -48,8 +50,9 @@ var HealthCheckResponse_ServingStatus_value = map[string]int32{ func (x HealthCheckResponse_ServingStatus) String() string { return proto.EnumName(HealthCheckResponse_ServingStatus_name, int32(x)) } + func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_health_6b1a06aa67f91efd, []int{1, 0} + return fileDescriptor_e265fd9d4e077217, []int{1, 0} } type HealthCheckRequest struct { @@ -63,16 +66,17 @@ func (m *HealthCheckRequest) Reset() { *m = HealthCheckRequest{} } func (m *HealthCheckRequest) String() string { return proto.CompactTextString(m) } func (*HealthCheckRequest) ProtoMessage() {} func (*HealthCheckRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_health_6b1a06aa67f91efd, []int{0} + return fileDescriptor_e265fd9d4e077217, []int{0} } + func (m *HealthCheckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_HealthCheckRequest.Unmarshal(m, b) } func (m *HealthCheckRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_HealthCheckRequest.Marshal(b, m, deterministic) } -func (dst *HealthCheckRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_HealthCheckRequest.Merge(dst, src) +func (m *HealthCheckRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_HealthCheckRequest.Merge(m, src) } func (m *HealthCheckRequest) XXX_Size() int { return xxx_messageInfo_HealthCheckRequest.Size(m) @@ -101,16 +105,17 @@ func (m *HealthCheckResponse) Reset() { *m = HealthCheckResponse{} } func (m *HealthCheckResponse) String() string { return proto.CompactTextString(m) } func (*HealthCheckResponse) ProtoMessage() {} func (*HealthCheckResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_health_6b1a06aa67f91efd, []int{1} + return fileDescriptor_e265fd9d4e077217, []int{1} } + func (m *HealthCheckResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_HealthCheckResponse.Unmarshal(m, b) } func (m *HealthCheckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_HealthCheckResponse.Marshal(b, m, deterministic) } -func (dst *HealthCheckResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_HealthCheckResponse.Merge(dst, src) +func (m *HealthCheckResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_HealthCheckResponse.Merge(m, src) } func (m *HealthCheckResponse) XXX_Size() int { return xxx_messageInfo_HealthCheckResponse.Size(m) @@ -129,9 +134,34 @@ func (m *HealthCheckResponse) GetStatus() HealthCheckResponse_ServingStatus { } func init() { + proto.RegisterEnum("grpc.health.v1.HealthCheckResponse_ServingStatus", HealthCheckResponse_ServingStatus_name, HealthCheckResponse_ServingStatus_value) proto.RegisterType((*HealthCheckRequest)(nil), "grpc.health.v1.HealthCheckRequest") proto.RegisterType((*HealthCheckResponse)(nil), "grpc.health.v1.HealthCheckResponse") - proto.RegisterEnum("grpc.health.v1.HealthCheckResponse_ServingStatus", HealthCheckResponse_ServingStatus_name, HealthCheckResponse_ServingStatus_value) +} + +func init() { proto.RegisterFile("grpc/health/v1/health.proto", fileDescriptor_e265fd9d4e077217) } + +var fileDescriptor_e265fd9d4e077217 = []byte{ + // 297 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0x2f, 0x2a, 0x48, + 0xd6, 0xcf, 0x48, 0x4d, 0xcc, 0x29, 0xc9, 0xd0, 0x2f, 0x33, 0x84, 0xb2, 0xf4, 0x0a, 0x8a, 0xf2, + 0x4b, 0xf2, 0x85, 0xf8, 0x40, 0x92, 0x7a, 0x50, 0xa1, 0x32, 0x43, 0x25, 0x3d, 0x2e, 0x21, 0x0f, + 0x30, 0xc7, 0x39, 0x23, 0x35, 0x39, 0x3b, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x48, 0x82, + 0x8b, 0xbd, 0x38, 0xb5, 0xa8, 0x2c, 0x33, 0x39, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, + 0xc6, 0x55, 0xda, 0xc8, 0xc8, 0x25, 0x8c, 0xa2, 0xa1, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc8, + 0x93, 0x8b, 0xad, 0xb8, 0x24, 0xb1, 0xa4, 0xb4, 0x18, 0xac, 0x81, 0xcf, 0xc8, 0x50, 0x0f, 0xd5, + 0x22, 0x3d, 0x2c, 0x9a, 0xf4, 0x82, 0x41, 0x86, 0xe6, 0xa5, 0x07, 0x83, 0x35, 0x06, 0x41, 0x0d, + 0x50, 0xf2, 0xe7, 0xe2, 0x45, 0x91, 0x10, 0xe2, 0xe6, 0x62, 0x0f, 0xf5, 0xf3, 0xf6, 0xf3, 0x0f, + 0xf7, 0x13, 0x60, 0x00, 0x71, 0x82, 0x5d, 0x83, 0xc2, 0x3c, 0xfd, 0xdc, 0x05, 0x18, 0x85, 0xf8, + 0xb9, 0xb8, 0xfd, 0xfc, 0x43, 0xe2, 0x61, 0x02, 0x4c, 0x42, 0xc2, 0x5c, 0xfc, 0x60, 0x8e, 0xb3, + 0x6b, 0x3c, 0x4c, 0x0b, 0xb3, 0xd1, 0x3a, 0x46, 0x2e, 0x36, 0x88, 0xf5, 0x42, 0x01, 0x5c, 0xac, + 0x60, 0x27, 0x08, 0x29, 0xe1, 0x75, 0x1f, 0x38, 0x14, 0xa4, 0x94, 0x89, 0xf0, 0x83, 0x50, 0x10, + 0x17, 0x6b, 0x78, 0x62, 0x49, 0x72, 0x06, 0xd5, 0x4c, 0x34, 0x60, 0x74, 0x4a, 0xe4, 0x12, 0xcc, + 0xcc, 0x47, 0x53, 0xea, 0xc4, 0x0d, 0x51, 0x1b, 0x00, 0x8a, 0xc6, 0x00, 0xc6, 0x28, 0x9d, 0xf4, + 0xfc, 0xfc, 0xf4, 0x9c, 0x54, 0xbd, 0xf4, 0xfc, 0x9c, 0xc4, 0xbc, 0x74, 0xbd, 0xfc, 0xa2, 0x74, + 0x7d, 0xe4, 0x78, 0x07, 0xb1, 0xe3, 0x21, 0xec, 0xf8, 0x32, 0xc3, 0x55, 0x4c, 0x7c, 0xee, 0x20, + 0xd3, 0x20, 0x46, 0xe8, 0x85, 0x19, 0x26, 0xb1, 0x81, 0x93, 0x83, 0x31, 0x20, 0x00, 0x00, 0xff, + 0xff, 0x12, 0x7d, 0x96, 0xcb, 0x2d, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -239,6 +269,17 @@ type HealthServer interface { Watch(*HealthCheckRequest, Health_WatchServer) error } +// UnimplementedHealthServer can be embedded to have forward compatible implementations. +type UnimplementedHealthServer struct { +} + +func (*UnimplementedHealthServer) Check(ctx context.Context, req *HealthCheckRequest) (*HealthCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") +} +func (*UnimplementedHealthServer) Watch(req *HealthCheckRequest, srv Health_WatchServer) error { + return status.Errorf(codes.Unimplemented, "method Watch not implemented") +} + func RegisterHealthServer(s *grpc.Server, srv HealthServer) { s.RegisterService(&_Health_serviceDesc, srv) } @@ -300,28 +341,3 @@ var _Health_serviceDesc = grpc.ServiceDesc{ }, Metadata: "grpc/health/v1/health.proto", } - -func init() { proto.RegisterFile("grpc/health/v1/health.proto", fileDescriptor_health_6b1a06aa67f91efd) } - -var fileDescriptor_health_6b1a06aa67f91efd = []byte{ - // 297 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0x2f, 0x2a, 0x48, - 0xd6, 0xcf, 0x48, 0x4d, 0xcc, 0x29, 0xc9, 0xd0, 0x2f, 0x33, 0x84, 0xb2, 0xf4, 0x0a, 0x8a, 0xf2, - 0x4b, 0xf2, 0x85, 0xf8, 0x40, 0x92, 0x7a, 0x50, 0xa1, 0x32, 0x43, 0x25, 0x3d, 0x2e, 0x21, 0x0f, - 0x30, 0xc7, 0x39, 0x23, 0x35, 0x39, 0x3b, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x48, 0x82, - 0x8b, 0xbd, 0x38, 0xb5, 0xa8, 0x2c, 0x33, 0x39, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, - 0xc6, 0x55, 0xda, 0xc8, 0xc8, 0x25, 0x8c, 0xa2, 0xa1, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc8, - 0x93, 0x8b, 0xad, 0xb8, 0x24, 0xb1, 0xa4, 0xb4, 0x18, 0xac, 0x81, 0xcf, 0xc8, 0x50, 0x0f, 0xd5, - 0x22, 0x3d, 0x2c, 0x9a, 0xf4, 0x82, 0x41, 0x86, 0xe6, 0xa5, 0x07, 0x83, 0x35, 0x06, 0x41, 0x0d, - 0x50, 0xf2, 0xe7, 0xe2, 0x45, 0x91, 0x10, 0xe2, 0xe6, 0x62, 0x0f, 0xf5, 0xf3, 0xf6, 0xf3, 0x0f, - 0xf7, 0x13, 0x60, 0x00, 0x71, 0x82, 0x5d, 0x83, 0xc2, 0x3c, 0xfd, 0xdc, 0x05, 0x18, 0x85, 0xf8, - 0xb9, 0xb8, 0xfd, 0xfc, 0x43, 0xe2, 0x61, 0x02, 0x4c, 0x42, 0xc2, 0x5c, 0xfc, 0x60, 0x8e, 0xb3, - 0x6b, 0x3c, 0x4c, 0x0b, 0xb3, 0xd1, 0x3a, 0x46, 0x2e, 0x36, 0x88, 0xf5, 0x42, 0x01, 0x5c, 0xac, - 0x60, 0x27, 0x08, 0x29, 0xe1, 0x75, 0x1f, 0x38, 0x14, 0xa4, 0x94, 0x89, 0xf0, 0x83, 0x50, 0x10, - 0x17, 0x6b, 0x78, 0x62, 0x49, 0x72, 0x06, 0xd5, 0x4c, 0x34, 0x60, 0x74, 0x4a, 0xe4, 0x12, 0xcc, - 0xcc, 0x47, 0x53, 0xea, 0xc4, 0x0d, 0x51, 0x1b, 0x00, 0x8a, 0xc6, 0x00, 0xc6, 0x28, 0x9d, 0xf4, - 0xfc, 0xfc, 0xf4, 0x9c, 0x54, 0xbd, 0xf4, 0xfc, 0x9c, 0xc4, 0xbc, 0x74, 0xbd, 0xfc, 0xa2, 0x74, - 0x7d, 0xe4, 0x78, 0x07, 0xb1, 0xe3, 0x21, 0xec, 0xf8, 0x32, 0xc3, 0x55, 0x4c, 0x7c, 0xee, 0x20, - 0xd3, 0x20, 0x46, 0xe8, 0x85, 0x19, 0x26, 0xb1, 0x81, 0x93, 0x83, 0x31, 0x20, 0x00, 0x00, 0xff, - 0xff, 0x12, 0x7d, 0x96, 0xcb, 0x2d, 0x02, 0x00, 0x00, -} diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index b8e0aa4db..ddee20b6b 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -107,8 +107,8 @@ func (*registerStream) isTransportResponseFrame() bool { return false } type headerFrame struct { streamID uint32 hf []hpack.HeaderField - endStream bool // Valid on server side. - initStream func(uint32) (bool, error) // Used only on the client side. + endStream bool // Valid on server side. + initStream func(uint32) error // Used only on the client side. onWrite func() wq *writeQuota // write quota for the stream created. cleanup *cleanupStream // Valid on the server side. @@ -637,21 +637,17 @@ func (l *loopyWriter) headerHandler(h *headerFrame) error { func (l *loopyWriter) originateStream(str *outStream) error { hdr := str.itl.dequeue().(*headerFrame) - sendPing, err := hdr.initStream(str.id) - if err != nil { + if err := hdr.initStream(str.id); err != nil { if err == ErrConnClosing { return err } // Other errors(errStreamDrain) need not close transport. return nil } - if err = l.writeHeader(str.id, hdr.endStream, hdr.hf, hdr.onWrite); err != nil { + if err := l.writeHeader(str.id, hdr.endStream, hdr.hf, hdr.onWrite); err != nil { return err } l.estdStreams[str.id] = str - if sendPing { - return l.pingHandler(&ping{data: [8]byte{}}) - } return nil } diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index 41a79c567..9bd8c27b3 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -62,8 +62,6 @@ type http2Client struct { // goAway is closed to notify the upper layer (i.e., addrConn.transportMonitor) // that the server sent GoAway on this transport. goAway chan struct{} - // awakenKeepalive is used to wake up keepalive when after it has gone dormant. - awakenKeepalive chan struct{} framer *framer // controlBuf delivers all the control related tasks (e.g., window @@ -110,6 +108,16 @@ type http2Client struct { // goAwayReason records the http2.ErrCode and debug data received with the // GoAway frame. goAwayReason GoAwayReason + // A condition variable used to signal when the keepalive goroutine should + // go dormant. The condition for dormancy is based on the number of active + // streams and the `PermitWithoutStream` keepalive client parameter. And + // since the number of active streams is guarded by the above mutex, we use + // the same for this condition variable as well. + kpDormancyCond *sync.Cond + // A boolean to track whether the keepalive goroutine is dormant or not. + // This is checked before attempting to signal the above condition + // variable. + kpDormant bool // Fields below are for channelz metric collection. channelzID int64 // channelz unique identification number @@ -232,7 +240,6 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne readerDone: make(chan struct{}), writerDone: make(chan struct{}), goAway: make(chan struct{}), - awakenKeepalive: make(chan struct{}, 1), framer: newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize), fc: &trInFlow{limit: uint32(icwz)}, scheme: scheme, @@ -264,9 +271,6 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne updateFlowControl: t.updateFlowControl, } } - // Make sure awakenKeepalive can't be written upon. - // keepalive routine will make it writable, if need be. - t.awakenKeepalive <- struct{}{} if t.statsHandler != nil { t.ctx = t.statsHandler.TagConn(t.ctx, &stats.ConnTagInfo{ RemoteAddr: t.remoteAddr, @@ -281,6 +285,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne t.channelzID = channelz.RegisterNormalSocket(t, opts.ChannelzParentID, fmt.Sprintf("%s -> %s", t.localAddr, t.remoteAddr)) } if t.keepaliveEnabled { + t.kpDormancyCond = sync.NewCond(&t.mu) go t.keepalive() } // Start the reader goroutine for incoming message. Each transport has @@ -564,7 +569,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea hdr := &headerFrame{ hf: headerFields, endStream: false, - initStream: func(id uint32) (bool, error) { + initStream: func(id uint32) error { t.mu.Lock() if state := t.state; state != reachable { t.mu.Unlock() @@ -574,29 +579,19 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea err = ErrConnClosing } cleanup(err) - return false, err + return err } t.activeStreams[id] = s if channelz.IsOn() { atomic.AddInt64(&t.czData.streamsStarted, 1) atomic.StoreInt64(&t.czData.lastStreamCreatedTime, time.Now().UnixNano()) } - var sendPing bool - // If the number of active streams change from 0 to 1, then check if keepalive - // has gone dormant. If so, wake it up. - if len(t.activeStreams) == 1 && t.keepaliveEnabled { - select { - case t.awakenKeepalive <- struct{}{}: - sendPing = true - // Fill the awakenKeepalive channel again as this channel must be - // kept non-writable except at the point that the keepalive() - // goroutine is waiting either to be awaken or shutdown. - t.awakenKeepalive <- struct{}{} - default: - } + // If the keepalive goroutine has gone dormant, wake it up. + if t.kpDormant { + t.kpDormancyCond.Signal() } t.mu.Unlock() - return sendPing, nil + return nil }, onOrphaned: cleanup, wq: s.wq, @@ -778,6 +773,11 @@ func (t *http2Client) Close() error { t.state = closing streams := t.activeStreams t.activeStreams = nil + if t.kpDormant { + // If the keepalive goroutine is blocked on this condition variable, we + // should unblock it so that the goroutine eventually exits. + t.kpDormancyCond.Signal() + } t.mu.Unlock() t.controlBuf.finish() t.cancel() @@ -853,11 +853,11 @@ func (t *http2Client) Write(s *Stream, hdr []byte, data []byte, opts *Options) e return t.controlBuf.put(df) } -func (t *http2Client) getStream(f http2.Frame) (*Stream, bool) { +func (t *http2Client) getStream(f http2.Frame) *Stream { t.mu.Lock() - defer t.mu.Unlock() - s, ok := t.activeStreams[f.Header().StreamID] - return s, ok + s := t.activeStreams[f.Header().StreamID] + t.mu.Unlock() + return s } // adjustWindow sends out extra window update over the initial window size @@ -937,8 +937,8 @@ func (t *http2Client) handleData(f *http2.DataFrame) { t.controlBuf.put(bdpPing) } // Select the right stream to dispatch. - s, ok := t.getStream(f) - if !ok { + s := t.getStream(f) + if s == nil { return } if size > 0 { @@ -969,8 +969,8 @@ func (t *http2Client) handleData(f *http2.DataFrame) { } func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) { - s, ok := t.getStream(f) - if !ok { + s := t.getStream(f) + if s == nil { return } if f.ErrCode == http2.ErrCodeRefusedStream { @@ -1147,8 +1147,8 @@ func (t *http2Client) handleWindowUpdate(f *http2.WindowUpdateFrame) { // operateHeaders takes action on the decoded headers. func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { - s, ok := t.getStream(frame) - if !ok { + s := t.getStream(frame) + if s == nil { return } endStream := frame.StreamEnded() @@ -1303,29 +1303,32 @@ func (t *http2Client) keepalive() { timer.Reset(t.kp.Time) continue } - // Check if keepalive should go dormant. t.mu.Lock() - if len(t.activeStreams) < 1 && !t.kp.PermitWithoutStream { - // Make awakenKeepalive writable. - <-t.awakenKeepalive + if t.state == closing { + // If the transport is closing, we should exit from the + // keepalive goroutine here. If not, we could have a race + // between the call to Signal() from Close() and the call to + // Wait() here, whereby the keepalive goroutine ends up + // blocking on the condition variable which will never be + // signalled again. t.mu.Unlock() - select { - case <-t.awakenKeepalive: - // If the control gets here a ping has been sent - // need to reset the timer with keepalive.Timeout. - case <-t.ctx.Done(): - return - } - } else { - t.mu.Unlock() - if channelz.IsOn() { - atomic.AddInt64(&t.czData.kpCount, 1) - } - // Send ping. - t.controlBuf.put(p) + return } + if len(t.activeStreams) < 1 && !t.kp.PermitWithoutStream { + t.kpDormant = true + t.kpDormancyCond.Wait() + } + t.kpDormant = false + t.mu.Unlock() + + if channelz.IsOn() { + atomic.AddInt64(&t.czData.kpCount, 1) + } + // We get here either because we were dormant and a new stream was + // created which unblocked the Wait() call, or because the + // keepalive timer expired. In both cases, we need to send a ping. + t.controlBuf.put(p) - // By the time control gets here a ping has been sent one way or the other. timer.Reset(t.kp.Timeout) select { case <-timer.C: diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index 4e26f6a1d..33686a11a 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -65,8 +65,7 @@ var ( // http2Server implements the ServerTransport interface with HTTP2. type http2Server struct { ctx context.Context - ctxDone <-chan struct{} // Cache the context.Done() chan - cancel context.CancelFunc + done chan struct{} conn net.Conn loopy *loopyWriter readerDone chan struct{} // sync point to enable testing. @@ -206,11 +205,10 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err if kep.MinTime == 0 { kep.MinTime = defaultKeepalivePolicyMinTime } - ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) t := &http2Server{ - ctx: ctx, - cancel: cancel, - ctxDone: ctx.Done(), + ctx: context.Background(), + done: done, conn: conn, remoteAddr: conn.RemoteAddr(), localAddr: conn.LocalAddr(), @@ -231,7 +229,7 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err czData: new(channelzData), bufferPool: newBufferPool(), } - t.controlBuf = newControlBuffer(t.ctxDone) + t.controlBuf = newControlBuffer(t.done) if dynamicWindow { t.bdpEst = &bdpEstimator{ bdp: initialWindowSize, @@ -362,12 +360,14 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( rstCode: http2.ErrCodeRefusedStream, onWrite: func() {}, }) + s.cancel() return false } } t.mu.Lock() if t.state != reachable { t.mu.Unlock() + s.cancel() return false } if uint32(len(t.activeStreams)) >= t.maxStreams { @@ -378,12 +378,14 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( rstCode: http2.ErrCodeRefusedStream, onWrite: func() {}, }) + s.cancel() return false } if streamID%2 != 1 || streamID <= t.maxStreamID { t.mu.Unlock() // illegal gRPC stream id. errorf("transport: http2Server.HandleStreams received an illegal stream id: %v", streamID) + s.cancel() return true } t.maxStreamID = streamID @@ -885,7 +887,7 @@ func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) e // TODO(mmukhi, dfawley): Should the server write also return io.EOF? s.cancel() select { - case <-t.ctx.Done(): + case <-t.done: return ErrConnClosing default: } @@ -907,7 +909,7 @@ func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) e } if err := s.wq.get(int32(len(hdr) + len(data))); err != nil { select { - case <-t.ctx.Done(): + case <-t.done: return ErrConnClosing default: } @@ -973,7 +975,7 @@ func (t *http2Server) keepalive() { t.Close() // Resetting the timer so that the clean-up doesn't deadlock. maxAge.Reset(infinity) - case <-t.ctx.Done(): + case <-t.done: } return case <-keepalive.C: @@ -995,7 +997,7 @@ func (t *http2Server) keepalive() { } t.controlBuf.put(p) keepalive.Reset(t.kp.Timeout) - case <-t.ctx.Done(): + case <-t.done: return } } @@ -1015,7 +1017,7 @@ func (t *http2Server) Close() error { t.activeStreams = nil t.mu.Unlock() t.controlBuf.finish() - t.cancel() + close(t.done) err := t.conn.Close() if channelz.IsOn() { channelz.RemoveEntry(t.channelzID) @@ -1155,7 +1157,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { select { case <-t.drainChan: case <-timer.C: - case <-t.ctx.Done(): + case <-t.done: return } t.controlBuf.put(&goAway{code: g.code, debugData: g.debugData}) @@ -1205,7 +1207,7 @@ func (t *http2Server) getOutFlowWindow() int64 { select { case sz := <-resp: return int64(sz) - case <-t.ctxDone: + case <-t.done: return -1 case <-timer.C: return -2 diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index d0787f1e2..686ad7ba6 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -310,6 +310,14 @@ func parseServiceConfig(js string) (*ServiceConfig, error) { } break } + if sc.lbConfig == nil { + // We had a loadBalancingConfig field but did not encounter a + // supported policy. The config is considered invalid in this + // case. + err := fmt.Errorf("invalid loadBalancingConfig: no supported policies found") + grpclog.Warningf(err.Error()) + return nil, err + } } if rsc.MethodConfig == nil { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 588850563..483ef8968 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.23.1" +const Version = "1.24.0" From 036cb96fd1e94b8cfc696d9d3c84c55330117ddd Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Mon, 30 Sep 2019 13:26:51 -0400 Subject: [PATCH 30/33] *: create project governance Create project governance. --- CHANGELOG-3.5.md | 3 +++ GOVERNANCE.md | 18 +++++------------- MAINTAINERS | 6 +----- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/CHANGELOG-3.5.md b/CHANGELOG-3.5.md index e9f815e12..656679a7e 100644 --- a/CHANGELOG-3.5.md +++ b/CHANGELOG-3.5.md @@ -102,6 +102,9 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Require [*Go 1.13+*](https://github.com/etcd-io/etcd/pull/11110). - Compile with [*Go 1.13*](https://golang.org/doc/devel/release.html#go1.13) +### Project Governance + +- The etcd team has added, a well defined and openly discussed, project [governance](https://github.com/etcd-io/etcd/pull/11175).
diff --git a/GOVERNANCE.md b/GOVERNANCE.md index b7d10081f..a0a6a290e 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -42,7 +42,7 @@ below. Contributors who are interested in becoming a maintainer, if performing these responsibilities, should discuss their interest with the existing maintainers. New maintainers must be nominated by an existing maintainer and must be elected by a -supermajority of maintainers. Likewise, maintainers can be removed by a supermajority +supermajority of maintainers. Likewise, maintainers can be removed by a supermajority of the maintainers and moved to emeritus status. Life priorities, interests, and passions can change. If a maintainer needs to step @@ -51,22 +51,14 @@ to pick up the related work. At the very least, ensure the related work can be c Afterward, create a pull request to remove yourself from the [MAINTAINERS](./MAINTAINERS) file. -## Approvers - -[Approvers](./MAINTAINERS) are contributors with merge rights. They are active reviewers -and have created significant numbers of PRs in the various code areas to add new features, -fix bugs and improve code. New approvers must be nominated by an existing maintainer -and must be elected by a supermajority of maintainers. Likewise, approvers can be removed -by a supermajority of the maintainers or can resign by notifying the maintainers. - ## Reviewers [Reviewers](./MAINTAINERS) are contributors who have demonstrated greater skill in reviewing the code contribution from other contributors. Their LGTM counts towards -merging a code change into the project. New reviewers must be nominated by an existing -maintainer and must be elected by a supermajority of maintainers. Likewise, reviewers -can be removed by a supermajority of the maintainers or can resign by notifying the -maintainers. +merging a code change into the project. A reviewer is generally on the ladder towards +maintainership. New reviewers must be nominated by an existing maintainer and must be +elected by a supermajority of maintainers. Likewise, reviewers can be removed by a +supermajority of the maintainers or can resign by notifying the maintainers. ## Decision making process diff --git a/MAINTAINERS b/MAINTAINERS index fd85ff1e2..b42a28e53 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1,4 +1,4 @@ -# The official list of maintainers, approvers, and reviewers for the project maintenance. +# The official list of maintainers and reviewers for the project maintenance. # # Refer to the GOVERNANCE.md for description of the roles. # @@ -21,9 +21,5 @@ Xiang Li (@xiang90) pkg:* Ben Darnell (@bdarnell) pkg:go.etcd.io/etcd/raft Tobias Grieger (@tbg) pkg:go.etcd.io/etcd/raft -# APPROVERS -Anthony Romano (@heyitsanthony) pkg:* -Fanmin Shi (@fanminshi) pkg:* - # REVIEWERS Wenjia Zhang (@wenjiaswe) pkg:* From d487b16de17f4dfb54b0b47e41e054d517f36284 Mon Sep 17 00:00:00 2001 From: Ilya Sevostyanov Date: Tue, 1 Oct 2019 10:10:56 +0300 Subject: [PATCH 31/33] confchange: removed duplicate check in confchange.Simple. --- raft/confchange/confchange.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/raft/confchange/confchange.go b/raft/confchange/confchange.go index a0dc486df..741f81115 100644 --- a/raft/confchange/confchange.go +++ b/raft/confchange/confchange.go @@ -142,9 +142,6 @@ func (c Changer) Simple(ccs ...pb.ConfChangeSingle) (tracker.Config, tracker.Pro if n := symdiff(incoming(c.Tracker.Voters), incoming(cfg.Voters)); n > 1 { return tracker.Config{}, nil, errors.New("more than one voter changed without entering joint config") } - if err := checkInvariants(cfg, prs); err != nil { - return tracker.Config{}, tracker.ProgressMap{}, nil - } return checkAndReturn(cfg, prs) } From a5abf917719ece8a4af476f0e052798265d633a9 Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Wed, 2 Oct 2019 17:43:32 -0700 Subject: [PATCH 32/33] etcdctl: fix member add command --- etcdctl/ctlv3/command/member_command.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/etcdctl/ctlv3/command/member_command.go b/etcdctl/ctlv3/command/member_command.go index 182ff8ef7..239c34ca4 100644 --- a/etcdctl/ctlv3/command/member_command.go +++ b/etcdctl/ctlv3/command/member_command.go @@ -158,12 +158,14 @@ func memberAddCommandFunc(cmd *cobra.Command, args []string) { if _, ok := (display).(*simplePrinter); ok { ctx, cancel = commandCtx(cmd) listResp, err := cli.MemberList(ctx) - // get latest member list; if there's failover new member might have outdated list + // make sure the member who served member list request has the latest member list. + syncedMemberSet := make(map[uint64]struct{}) + syncedMemberSet[resp.Header.MemberId] = struct{}{} // the member who served member add is guaranteed to have the latest member list. for { if err != nil { ExitWithError(ExitError, err) } - if listResp.Header.MemberId == resp.Header.MemberId { + if _, ok := syncedMemberSet[listResp.Header.MemberId]; ok { break } // quorum get to sync cluster list @@ -171,7 +173,7 @@ func memberAddCommandFunc(cmd *cobra.Command, args []string) { if gerr != nil { ExitWithError(ExitError, err) } - resp.Header.MemberId = gresp.Header.MemberId + syncedMemberSet[gresp.Header.MemberId] = struct{}{} listResp, err = cli.MemberList(ctx) } cancel() From 2bf8e03c730d9625082272119a9835a0b2af4272 Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Thu, 3 Oct 2019 14:00:22 -0700 Subject: [PATCH 33/33] CHANGELOG: update from #11194 --- CHANGELOG-3.3.md | 4 ++++ CHANGELOG-3.4.md | 4 ++++ CHANGELOG-3.5.md | 3 +++ 3 files changed, 11 insertions(+) diff --git a/CHANGELOG-3.3.md b/CHANGELOG-3.3.md index efdfe34a7..e510eb82f 100644 --- a/CHANGELOG-3.3.md +++ b/CHANGELOG-3.3.md @@ -28,6 +28,10 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Upgrade [`github.com/coreos/bbolt`](https://github.com/etcd-io/bbolt/releases) from [**`v1.3.1-coreos.6`**](https://github.com/etcd-io/bbolt/releases/tag/v1.3.1-coreos.6) to [**`v1.3.3`**](https://github.com/etcd-io/bbolt/releases/tag/v1.3.3). +### etcdctl v3 + +- Fix [`etcdctl member add`](https://github.com/etcd-io/etcd/pull/11194) command to prevent potential timeout. + ### Go - Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes. diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index b5ff8b2ae..494960d3e 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -19,6 +19,10 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.1...v3.4.2) and - Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) from [**`v1.23.1`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.1) to [**`v1.24.0`**](https://github.com/grpc/grpc-go/releases/tag/v1.24.0). +### etcdctl v3 + +- Fix [`etcdctl member add`](https://github.com/etcd-io/etcd/pull/11194) command to prevent potential timeout. + ### Go - Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes. diff --git a/CHANGELOG-3.5.md b/CHANGELOG-3.5.md index 656679a7e..8d769e20a 100644 --- a/CHANGELOG-3.5.md +++ b/CHANGELOG-3.5.md @@ -86,6 +86,9 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change. - Add [TryLock](https://github.com/etcd-io/etcd/pull/11104) method to `clientv3/concurrency/Mutex`. A non-blocking method on `Mutex` which does not wait to get lock on the Mutex, returns immediately if Mutex is locked by another session. +### etcdctl v3 + +- Fix [`etcdctl member add`](https://github.com/etcd-io/etcd/pull/11194) command to prevent potential timeout. ### gRPC gateway