Skip to content

Commit

Permalink
Ensure Keys are watchable with etcd
Browse files Browse the repository at this point in the history
etcd v2.0+ with API v2 cannot watch on a regular key, we must enforce
the 'IsDir' parameter while creating the key for it to be considered
as a directory.

This step is necessary unless 'libkv' includes and supports the new
etcd API v3 which removes the directory/key distinction to allow for
a better abstraction.

Fixes: moby#392
See: docker/libkv#20

Signed-off-by: Alexandre Beslic <abronan@docker.com>
  • Loading branch information
abronan committed Oct 3, 2015
1 parent 0bf5afe commit 9dac5bc
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions store.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func (c *controller) watchNetworks() error {
c.Unlock()

networkKey := datastore.Key(datastore.NetworkKeyPrefix)
if err := ensureKeys(networkKey, cs); err != nil {
if err := ensureWatchable(networkKey, cs); err != nil {
return fmt.Errorf("failed to ensure if the network keys are valid and present in store: %v", err)
}
nwPairs, err := cs.KVStore().WatchTree(networkKey, nil)
Expand Down Expand Up @@ -225,7 +225,7 @@ func (n *network) watchEndpoints() error {
n.Unlock()

endpointKey := datastore.Key(tmp.KeyPrefix()...)
if err := ensureKeys(endpointKey, cs); err != nil {
if err := ensureWatchable(endpointKey, cs); err != nil {
return fmt.Errorf("failed to ensure if the endpoint keys are valid and present in store: %v", err)
}
epPairs, err := cs.KVStore().WatchTree(endpointKey, stopCh)
Expand Down Expand Up @@ -346,15 +346,21 @@ func (c *controller) processEndpointUpdate(ep *endpoint) bool {
return false
}

func ensureKeys(key string, cs datastore.DataStore) error {
// ensureWatchable ensures that the key named 'path'
// is watchable by the backend store client.
//
// FIXME because etcd cannot watch on a regular key,
// we enforce 'IsDir' at true so that the key can be
// considered as a directory and thus be watchable.
func ensureWatchable(key string, cs datastore.DataStore) error {
exists, err := cs.KVStore().Exists(key)
if err != nil {
return err
}
if exists {
return nil
}
return cs.KVStore().Put(key, []byte{}, nil)
return cs.KVStore().Put(key, []byte{}, &store.WriteOptions{IsDir: true})
}

func (c *controller) getLocalStoreConfig(cfg *config.Config) *config.DatastoreCfg {
Expand Down

0 comments on commit 9dac5bc

Please sign in to comment.