@@ -216,11 +216,10 @@ func New(ctx context.Context, params backend.Params) (*EtcdBackend, error) {
216
216
buf : buf ,
217
217
}
218
218
219
+ // Check that the etcd nodes are at least the minimum version supported
219
220
if err = b .reconnect (ctx ); err != nil {
220
221
return nil , trace .Wrap (err )
221
222
}
222
-
223
- // Check that the etcd nodes are at least the minimum version supported
224
223
timeout , cancel := context .WithTimeout (ctx , time .Second * 3 * time .Duration (len (cfg .Nodes )))
225
224
defer cancel ()
226
225
for _ , n := range cfg .Nodes {
@@ -237,6 +236,13 @@ func New(ctx context.Context, params backend.Params) (*EtcdBackend, error) {
237
236
}
238
237
}
239
238
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
+
240
246
// Wrap backend in a input sanitizer and return it.
241
247
return b , nil
242
248
}
@@ -292,6 +298,12 @@ func (b *EtcdBackend) CloseWatchers() {
292
298
}
293
299
294
300
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
+
295
307
tlsConfig := utils .TLSConfig (nil )
296
308
297
309
if b .cfg .TLSCertFile != "" {
@@ -340,7 +352,6 @@ func (b *EtcdBackend) reconnect(ctx context.Context) error {
340
352
return trace .Wrap (err )
341
353
}
342
354
b .client = clt
343
- go b .asyncWatch ()
344
355
return nil
345
356
}
346
357
0 commit comments