Skip to content

Commit 3f74b2d

Browse files
author
Andrew Lytvynov
committed
etcd: use a separate connection to check peer versions
There is a data race in etcd that breaks the internal state in etcd client implementation for some server setups (user/pass authentication with JWTs).
1 parent 1a72b39 commit 3f74b2d

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

lib/backend/etcdbk/etcd.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,10 @@ func New(ctx context.Context, params backend.Params) (*EtcdBackend, error) {
216216
buf: buf,
217217
}
218218

219+
// Check that the etcd nodes are at least the minimum version supported
219220
if err = b.reconnect(ctx); err != nil {
220221
return nil, trace.Wrap(err)
221222
}
222-
223-
// Check that the etcd nodes are at least the minimum version supported
224223
timeout, cancel := context.WithTimeout(ctx, time.Second*3*time.Duration(len(cfg.Nodes)))
225224
defer cancel()
226225
for _, n := range cfg.Nodes {
@@ -237,6 +236,13 @@ func New(ctx context.Context, params backend.Params) (*EtcdBackend, error) {
237236
}
238237
}
239238

239+
// Reconnect the etcd client to work around a data race in their code.
240+
// Upstream fix: https://github.com/etcd-io/etcd/pull/12992
241+
if err = b.reconnect(ctx); err != nil {
242+
return nil, trace.Wrap(err)
243+
}
244+
go b.asyncWatch()
245+
240246
// Wrap backend in a input sanitizer and return it.
241247
return b, nil
242248
}
@@ -292,6 +298,12 @@ func (b *EtcdBackend) CloseWatchers() {
292298
}
293299

294300
func (b *EtcdBackend) reconnect(ctx context.Context) error {
301+
if b.client != nil {
302+
if err := b.client.Close(); err != nil {
303+
b.Entry.WithError(err).Warningf("Failed closing existing etcd client on reconnect.")
304+
}
305+
}
306+
295307
tlsConfig := utils.TLSConfig(nil)
296308

297309
if b.cfg.TLSCertFile != "" {
@@ -340,7 +352,6 @@ func (b *EtcdBackend) reconnect(ctx context.Context) error {
340352
return trace.Wrap(err)
341353
}
342354
b.client = clt
343-
go b.asyncWatch()
344355
return nil
345356
}
346357

0 commit comments

Comments
 (0)