From fa5cd27d821d9a53b9047c07036058275ad25db6 Mon Sep 17 00:00:00 2001 From: Alexandre Beslic Date: Tue, 6 Oct 2015 17:12:16 -0700 Subject: [PATCH 1/2] Initialize the key/directory before watching on kv discovery Before that change, etcd and zookeeper would fail to instantiate the discovery without the key being already there in the store or created beforehand and implicitely by a 'swarm join'. Signed-off-by: Alexandre Beslic --- discovery/kv/kv.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/discovery/kv/kv.go b/discovery/kv/kv.go index 6e29d224a5..53c0803de2 100644 --- a/discovery/kv/kv.go +++ b/discovery/kv/kv.go @@ -112,6 +112,17 @@ func (s *Discovery) Watch(stopCh <-chan struct{}) (<-chan discovery.Entries, <-c // Forever: Create a store watch, watch until we get an error and then try again. // Will only stop if we receive a stopCh request. for { + // Create the path to watch if it does not exist yet + exists, err := s.store.Exists(s.path) + if err != nil { + errCh <- err + } + if !exists { + if err := s.store.Put(s.path, []byte(""), &store.WriteOptions{IsDir: true}); err != nil { + errCh <- err + } + } + // Set up a watch. watchCh, err := s.store.WatchTree(s.path, stopCh) if err != nil { From ab249c4756129453aaf8b323250368f24f782aba Mon Sep 17 00:00:00 2001 From: Alexandre Beslic Date: Thu, 8 Oct 2015 11:20:04 -0700 Subject: [PATCH 2/2] Fix tests by adding mocks for additional Watch calls Signed-off-by: Alexandre Beslic --- discovery/kv/kv_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/discovery/kv/kv_test.go b/discovery/kv/kv_test.go index d1e827db7a..e313047d3e 100644 --- a/discovery/kv/kv_test.go +++ b/discovery/kv/kv_test.go @@ -69,8 +69,11 @@ func TestWatch(t *testing.T) { s := d.store.(*libkvmock.Mock) mockCh := make(chan []*store.KVPair) - // The first watch will fail. + // The first watch will fail on those three calls + s.On("Exists", "path/"+discoveryPath).Return(false, errors.New("test error")) + s.On("Put", "path/"+discoveryPath, mock.Anything, mock.Anything).Return(errors.New("test error")) s.On("WatchTree", "path/"+discoveryPath, mock.Anything).Return(mockCh, errors.New("test error")).Once() + // The second one will succeed. s.On("WatchTree", "path/"+discoveryPath, mock.Anything).Return(mockCh, nil).Once() expected := discovery.Entries{ @@ -89,7 +92,7 @@ func TestWatch(t *testing.T) { assert.EqualError(t, <-errCh, "test error") // We have to drain the error channel otherwise Watch will get stuck. go func() { - for _ = range errCh { + for range errCh { } }()