Package: src:golang-github-docker-libnetwork
Version: 0.7.0~rc.6+dfsg-2
Severity: serious

The newest upload of "docker-libkv" changed the API slightly, causing
the current libnetwork version to FTBFS.

| # github.com/docker/libnetwork/datastore
| src/github.com/docker/libnetwork/datastore/cache.go:47: undefined:
boltdb.ErrBoltBucketNotFound

https://github.com/docker/libnetwork/commit/b6b3642560f59f930d1ecf49d2991d74077d05f9
(https://github.com/docker/libnetwork/pull/1120) from upstream appears
to be the appropriate fix.

I've done a build test with the attached patch (downloaded via
https://github.com/docker/libnetwork/commit/b6b3642560f59f930d1ecf49d2991d74077d05f9.patch
and only DEP-3 headers modified), and it appears to resolve the issue.

♥,
- Tianon
  4096R / B42F 6819 007F 00F8 8E36  4FD4 036A 9C25 BF35 7DD4
Subject: Remove kvstore deps from datastore package
Author: Jana Radhakrishnan <mrj...@docker.com>
Applied-Upstream: https://github.com/docker/libnetwork/commit/b6b3642560f59f930d1ecf49d2991d74077d05f9, https://github.com/docker/libnetwork/pull/1120, v0.8.0-dev.2

diff --git a/bitseq/sequence_test.go b/bitseq/sequence_test.go
index d435329..339f592 100644
--- a/bitseq/sequence_test.go
+++ b/bitseq/sequence_test.go
@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/docker/libkv/store"
+	"github.com/docker/libkv/store/boltdb"
 	"github.com/docker/libnetwork/datastore"
 	_ "github.com/docker/libnetwork/testutils"
 )
@@ -16,6 +17,10 @@ const (
 	defaultPrefix = "/tmp/libnetwork/test/bitseq"
 )
 
+func init() {
+	boltdb.Register()
+}
+
 func randomLocalStore() (datastore.DataStore, error) {
 	tmp, err := ioutil.TempFile("", "libnetwork-")
 	if err != nil {
diff --git a/datastore/cache.go b/datastore/cache.go
index 08c8ac4..2d00038 100644
--- a/datastore/cache.go
+++ b/datastore/cache.go
@@ -5,7 +5,6 @@ import (
 	"sync"
 
 	"github.com/docker/libkv/store"
-	"github.com/docker/libkv/store/boltdb"
 )
 
 type kvMap map[string]KVObject
@@ -42,9 +41,7 @@ func (c *cache) kmap(kvObject KVObject) (kvMap, error) {
 
 	kvList, err := c.ds.store.List(keyPrefix)
 	if err != nil {
-		// In case of BoltDB it may return ErrBoltBucketNotFound when no writes
-		// have ever happened on the db bucket. So check for both err codes
-		if err == store.ErrKeyNotFound || err == boltdb.ErrBoltBucketNotFound {
+		if err == store.ErrKeyNotFound {
 			// If the store doesn't have anything then there is nothing to
 			// populate in the cache. Just bail out.
 			goto out
diff --git a/datastore/datastore.go b/datastore/datastore.go
index c15cd62..49affc7 100644
--- a/datastore/datastore.go
+++ b/datastore/datastore.go
@@ -9,10 +9,6 @@ import (
 
 	"github.com/docker/libkv"
 	"github.com/docker/libkv/store"
-	"github.com/docker/libkv/store/boltdb"
-	"github.com/docker/libkv/store/consul"
-	"github.com/docker/libkv/store/etcd"
-	"github.com/docker/libkv/store/zookeeper"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/types"
 )
@@ -148,13 +144,6 @@ func makeDefaultScopes() map[string]*ScopeCfg {
 var defaultRootChain = []string{"docker", "network", "v1.0"}
 var rootChain = defaultRootChain
 
-func init() {
-	consul.Register()
-	zookeeper.Register()
-	etcd.Register()
-	boltdb.Register()
-}
-
 // DefaultScopes returns a map of default scopes and it's config for clients to use.
 func DefaultScopes(dataDir string) map[string]*ScopeCfg {
 	if dataDir != "" {
@@ -411,6 +400,9 @@ func (ds *datastore) PutObjectAtomic(kvObject KVObject) error {
 
 	_, pair, err = ds.store.AtomicPut(Key(kvObject.Key()...), kvObjValue, previous, nil)
 	if err != nil {
+		if err == store.ErrKeyExists {
+			return ErrKeyModified
+		}
 		return err
 	}
 
@@ -571,6 +563,9 @@ func (ds *datastore) DeleteObjectAtomic(kvObject KVObject) error {
 	}
 
 	if _, err := ds.store.AtomicDelete(Key(kvObject.Key()...), previous); err != nil {
+		if err == store.ErrKeyExists {
+			return ErrKeyModified
+		}
 		return err
 	}
 
diff --git a/drivers/bridge/bridge_store.go b/drivers/bridge/bridge_store.go
index eca72bd..de96352 100644
--- a/drivers/bridge/bridge_store.go
+++ b/drivers/bridge/bridge_store.go
@@ -6,7 +6,6 @@ import (
 	"net"
 
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/libkv/store/boltdb"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/netlabel"
@@ -35,7 +34,7 @@ func (d *driver) initStore(option map[string]interface{}) error {
 
 func (d *driver) populateNetworks() error {
 	kvol, err := d.store.List(datastore.Key(bridgePrefix), &networkConfiguration{})
-	if err != nil && err != datastore.ErrKeyNotFound && err != boltdb.ErrBoltBucketNotFound {
+	if err != nil && err != datastore.ErrKeyNotFound {
 		return fmt.Errorf("failed to get bridge network configurations from store: %v", err)
 	}
 
diff --git a/drivers/ipvlan/ipvlan_store.go b/drivers/ipvlan/ipvlan_store.go
index f6746da..c643083 100644
--- a/drivers/ipvlan/ipvlan_store.go
+++ b/drivers/ipvlan/ipvlan_store.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/libkv/store/boltdb"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/netlabel"
@@ -60,7 +59,7 @@ func (d *driver) initStore(option map[string]interface{}) error {
 // populateNetworks is invoked at driver init to recreate persistently stored networks
 func (d *driver) populateNetworks() error {
 	kvol, err := d.store.List(datastore.Key(ipvlanPrefix), &configuration{})
-	if err != nil && err != datastore.ErrKeyNotFound && err != boltdb.ErrBoltBucketNotFound {
+	if err != nil && err != datastore.ErrKeyNotFound {
 		return fmt.Errorf("failed to get ipvlan network configurations from store: %v", err)
 	}
 	// If empty it simply means no ipvlan networks have been created yet
diff --git a/drivers/macvlan/macvlan_store.go b/drivers/macvlan/macvlan_store.go
index 492ea93..5f92fea 100644
--- a/drivers/macvlan/macvlan_store.go
+++ b/drivers/macvlan/macvlan_store.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/libkv/store/boltdb"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/netlabel"
@@ -60,7 +59,7 @@ func (d *driver) initStore(option map[string]interface{}) error {
 // populateNetworks is invoked at driver init to recreate persistently stored networks
 func (d *driver) populateNetworks() error {
 	kvol, err := d.store.List(datastore.Key(macvlanPrefix), &configuration{})
-	if err != nil && err != datastore.ErrKeyNotFound && err != boltdb.ErrBoltBucketNotFound {
+	if err != nil && err != datastore.ErrKeyNotFound {
 		return fmt.Errorf("failed to get macvlan network configurations from store: %v", err)
 	}
 	// If empty it simply means no macvlan networks have been created yet
diff --git a/ipam/allocator.go b/ipam/allocator.go
index 70fe06e..8b4896f 100644
--- a/ipam/allocator.go
+++ b/ipam/allocator.go
@@ -6,6 +6,7 @@ import (
 	"sync"
 
 	log "github.com/Sirupsen/logrus"
+	"github.com/docker/libkv/store/boltdb"
 	"github.com/docker/libnetwork/bitseq"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
@@ -25,6 +26,10 @@ const (
 	dsDataKey   = "ipam/" + ipamapi.DefaultIPAM + "/data"
 )
 
+func init() {
+	boltdb.Register()
+}
+
 // Allocator provides per address space ipv4/ipv6 book keeping
 type Allocator struct {
 	// Predefined pools for default address spaces
diff --git a/store.go b/store.go
index 2c439dc..0e7ec19 100644
--- a/store.go
+++ b/store.go
@@ -4,9 +4,20 @@ import (
 	"fmt"
 
 	log "github.com/Sirupsen/logrus"
+	"github.com/docker/libkv/store/boltdb"
+	"github.com/docker/libkv/store/consul"
+	"github.com/docker/libkv/store/etcd"
+	"github.com/docker/libkv/store/zookeeper"
 	"github.com/docker/libnetwork/datastore"
 )
 
+func registerKVStores() {
+	consul.Register()
+	zookeeper.Register()
+	etcd.Register()
+	boltdb.Register()
+}
+
 func (c *controller) initScopedStore(scope string, scfg *datastore.ScopeCfg) error {
 	store, err := datastore.NewDataStore(scope, scfg)
 	if err != nil {
@@ -20,6 +31,8 @@ func (c *controller) initScopedStore(scope string, scfg *datastore.ScopeCfg) err
 }
 
 func (c *controller) initStores() error {
+	registerKVStores()
+
 	c.Lock()
 	if c.cfg == nil {
 		c.Unlock()

Reply via email to