mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Reading the top level element (network) from datastore on init
Currently we rely on watch to catchup after the init. But there could be a small time window on which, we might end up in a race condition on network creates. By reading and populating networks during init, we avoid any such conditions, especially for default network handling. Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
parent
1e1eaf5937
commit
8b59f48537
2 changed files with 51 additions and 30 deletions
|
@ -2,10 +2,11 @@ title = "LibNetwork Configuration file"
|
||||||
|
|
||||||
[daemon]
|
[daemon]
|
||||||
debug = false
|
debug = false
|
||||||
DefaultNetwork = "bridge"
|
|
||||||
DefaultDriver = "bridge"
|
|
||||||
[cluster]
|
[cluster]
|
||||||
discovery = "token://22aa23948f4f6b31230687689636959e"
|
discovery = "token://22aa23948f4f6b31230687689636959e"
|
||||||
Address = "1.1.1.1"
|
Address = "1.1.1.1"
|
||||||
[datastore]
|
[datastore]
|
||||||
embedded = false
|
embedded = false
|
||||||
|
[datastore.client]
|
||||||
|
provider = "consul"
|
||||||
|
Address = "localhost:8500"
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/libkv/store"
|
||||||
"github.com/docker/libnetwork/datastore"
|
"github.com/docker/libnetwork/datastore"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
)
|
)
|
||||||
|
@ -31,9 +32,23 @@ func (c *controller) initDataStore() error {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
c.store = store
|
c.store = store
|
||||||
c.Unlock()
|
c.Unlock()
|
||||||
|
|
||||||
|
nws, err := c.getNetworksFromStore()
|
||||||
|
if err == nil {
|
||||||
|
c.processNetworkUpdate(nws, nil)
|
||||||
|
} else if err != datastore.ErrKeyNotFound {
|
||||||
|
log.Warnf("failed to read networks from datastore during init : %v", err)
|
||||||
|
}
|
||||||
return c.watchNetworks()
|
return c.watchNetworks()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controller) getNetworksFromStore() ([]*store.KVPair, error) {
|
||||||
|
c.Lock()
|
||||||
|
cs := c.store
|
||||||
|
c.Unlock()
|
||||||
|
return cs.KVStore().List(datastore.Key(datastore.NetworkKeyPrefix))
|
||||||
|
}
|
||||||
|
|
||||||
func (c *controller) newNetworkFromStore(n *network) error {
|
func (c *controller) newNetworkFromStore(n *network) error {
|
||||||
n.Lock()
|
n.Lock()
|
||||||
n.ctrlr = c
|
n.ctrlr = c
|
||||||
|
@ -178,34 +193,7 @@ func (c *controller) watchNetworks() error {
|
||||||
for k, v := range lview {
|
for k, v := range lview {
|
||||||
tmpview[k] = v
|
tmpview[k] = v
|
||||||
}
|
}
|
||||||
for _, kve := range nws {
|
c.processNetworkUpdate(nws, &tmpview)
|
||||||
var n network
|
|
||||||
err := json.Unmarshal(kve.Value, &n)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
delete(tmpview, n.id)
|
|
||||||
n.dbIndex = kve.LastIndex
|
|
||||||
c.Lock()
|
|
||||||
existing, ok := c.networks[n.id]
|
|
||||||
c.Unlock()
|
|
||||||
if ok {
|
|
||||||
existing.Lock()
|
|
||||||
// Skip existing network update
|
|
||||||
if existing.dbIndex != n.dbIndex {
|
|
||||||
existing.dbIndex = n.dbIndex
|
|
||||||
existing.endpointCnt = n.endpointCnt
|
|
||||||
}
|
|
||||||
existing.Unlock()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = c.newNetworkFromStore(&n); err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// Delete processing
|
// Delete processing
|
||||||
for k := range tmpview {
|
for k := range tmpview {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
|
@ -305,6 +293,38 @@ func (n *network) stopWatch() {
|
||||||
n.Unlock()
|
n.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controller) processNetworkUpdate(nws []*store.KVPair, prune *networkTable) {
|
||||||
|
for _, kve := range nws {
|
||||||
|
var n network
|
||||||
|
err := json.Unmarshal(kve.Value, &n)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if prune != nil {
|
||||||
|
delete(*prune, n.id)
|
||||||
|
}
|
||||||
|
n.dbIndex = kve.LastIndex
|
||||||
|
c.Lock()
|
||||||
|
existing, ok := c.networks[n.id]
|
||||||
|
c.Unlock()
|
||||||
|
if ok {
|
||||||
|
existing.Lock()
|
||||||
|
// Skip existing network update
|
||||||
|
if existing.dbIndex != n.dbIndex {
|
||||||
|
existing.dbIndex = n.dbIndex
|
||||||
|
existing.endpointCnt = n.endpointCnt
|
||||||
|
}
|
||||||
|
existing.Unlock()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = c.newNetworkFromStore(&n); err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *controller) processEndpointUpdate(ep *endpoint) bool {
|
func (c *controller) processEndpointUpdate(ep *endpoint) bool {
|
||||||
nw := ep.network
|
nw := ep.network
|
||||||
if nw == nil {
|
if nw == nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue