|
@@ -31,7 +31,7 @@ func (c *controller) initDataStore() error {
|
|
c.Lock()
|
|
c.Lock()
|
|
c.store = store
|
|
c.store = store
|
|
c.Unlock()
|
|
c.Unlock()
|
|
- return c.watchStore()
|
|
|
|
|
|
+ return c.watchNetworks()
|
|
}
|
|
}
|
|
|
|
|
|
func (c *controller) newNetworkFromStore(n *network) error {
|
|
func (c *controller) newNetworkFromStore(n *network) error {
|
|
@@ -92,22 +92,6 @@ func (c *controller) newEndpointFromStore(key string, ep *endpoint) error {
|
|
n := ep.network
|
|
n := ep.network
|
|
id := ep.id
|
|
id := ep.id
|
|
ep.Unlock()
|
|
ep.Unlock()
|
|
- if n == nil {
|
|
|
|
- // Possibly the watch event for the network has not shown up yet
|
|
|
|
- // Try to get network from the store
|
|
|
|
- nid, err := networkIDFromEndpointKey(key, ep)
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- n, err = c.getNetworkFromStore(nid)
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- if err := c.newNetworkFromStore(n); err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- n = c.networks[nid]
|
|
|
|
- }
|
|
|
|
|
|
|
|
_, err := n.EndpointByID(string(id))
|
|
_, err := n.EndpointByID(string(id))
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -170,7 +154,11 @@ func (c *controller) deleteEndpointFromStore(ep *endpoint) error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func (c *controller) watchStore() error {
|
|
|
|
|
|
+func (c *controller) watchNetworks() error {
|
|
|
|
+ if !c.validateDatastoreConfig() {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
c.Lock()
|
|
c.Lock()
|
|
cs := c.store
|
|
cs := c.store
|
|
c.Unlock()
|
|
c.Unlock()
|
|
@@ -179,14 +167,17 @@ func (c *controller) watchStore() error {
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
- epPairs, err := cs.KVStore().WatchTree(datastore.Key(datastore.EndpointKeyPrefix), nil)
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
go func() {
|
|
go func() {
|
|
for {
|
|
for {
|
|
select {
|
|
select {
|
|
case nws := <-nwPairs:
|
|
case nws := <-nwPairs:
|
|
|
|
+ c.Lock()
|
|
|
|
+ tmpview := networkTable{}
|
|
|
|
+ lview := c.networks
|
|
|
|
+ c.Unlock()
|
|
|
|
+ for k, v := range lview {
|
|
|
|
+ tmpview[k] = v
|
|
|
|
+ }
|
|
for _, kve := range nws {
|
|
for _, kve := range nws {
|
|
var n network
|
|
var n network
|
|
err := json.Unmarshal(kve.Value, &n)
|
|
err := json.Unmarshal(kve.Value, &n)
|
|
@@ -194,6 +185,7 @@ func (c *controller) watchStore() error {
|
|
log.Error(err)
|
|
log.Error(err)
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
|
|
+ delete(tmpview, n.id)
|
|
n.dbIndex = kve.LastIndex
|
|
n.dbIndex = kve.LastIndex
|
|
c.Lock()
|
|
c.Lock()
|
|
existing, ok := c.networks[n.id]
|
|
existing, ok := c.networks[n.id]
|
|
@@ -212,8 +204,59 @@ func (c *controller) watchStore() error {
|
|
if err = c.newNetworkFromStore(&n); err != nil {
|
|
if err = c.newNetworkFromStore(&n); err != nil {
|
|
log.Error(err)
|
|
log.Error(err)
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+ // Delete processing
|
|
|
|
+ for k := range tmpview {
|
|
|
|
+ c.Lock()
|
|
|
|
+ existing, ok := c.networks[k]
|
|
|
|
+ c.Unlock()
|
|
|
|
+ if !ok {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ tmp := network{}
|
|
|
|
+ if err := c.store.GetObject(datastore.Key(existing.Key()...), &tmp); err != datastore.ErrKeyNotFound {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if err := existing.deleteNetwork(); err != nil {
|
|
|
|
+ log.Debugf("Delete failed %s: %s", existing.name, err)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }()
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (n *network) watchEndpoints() error {
|
|
|
|
+ if !n.ctrlr.validateDatastoreConfig() {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ n.Lock()
|
|
|
|
+ cs := n.ctrlr.store
|
|
|
|
+ tmp := endpoint{network: n}
|
|
|
|
+ n.stopWatchCh = make(chan struct{})
|
|
|
|
+ stopCh := n.stopWatchCh
|
|
|
|
+ n.Unlock()
|
|
|
|
+
|
|
|
|
+ epPairs, err := cs.KVStore().WatchTree(datastore.Key(tmp.KeyPrefix()...), stopCh)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ go func() {
|
|
|
|
+ for {
|
|
|
|
+ select {
|
|
|
|
+ case <-stopCh:
|
|
|
|
+ return
|
|
case eps := <-epPairs:
|
|
case eps := <-epPairs:
|
|
|
|
+ n.Lock()
|
|
|
|
+ tmpview := endpointTable{}
|
|
|
|
+ lview := n.endpoints
|
|
|
|
+ n.Unlock()
|
|
|
|
+ for k, v := range lview {
|
|
|
|
+ tmpview[k] = v
|
|
|
|
+ }
|
|
for _, epe := range eps {
|
|
for _, epe := range eps {
|
|
var ep endpoint
|
|
var ep endpoint
|
|
err := json.Unmarshal(epe.Value, &ep)
|
|
err := json.Unmarshal(epe.Value, &ep)
|
|
@@ -221,22 +264,30 @@ func (c *controller) watchStore() error {
|
|
log.Error(err)
|
|
log.Error(err)
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
|
|
+ delete(tmpview, ep.id)
|
|
ep.dbIndex = epe.LastIndex
|
|
ep.dbIndex = epe.LastIndex
|
|
- n, err := c.networkFromEndpointKey(epe.Key, &ep)
|
|
|
|
- if err != nil {
|
|
|
|
- if _, ok := err.(ErrNoSuchNetwork); !ok {
|
|
|
|
|
|
+ ep.network = n
|
|
|
|
+ if n.ctrlr.processEndpointUpdate(&ep) {
|
|
|
|
+ err = n.ctrlr.newEndpointFromStore(epe.Key, &ep)
|
|
|
|
+ if err != nil {
|
|
log.Error(err)
|
|
log.Error(err)
|
|
- continue
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if n != nil {
|
|
|
|
- ep.network = n.(*network)
|
|
|
|
|
|
+ }
|
|
|
|
+ // Delete processing
|
|
|
|
+ for k := range tmpview {
|
|
|
|
+ n.Lock()
|
|
|
|
+ existing, ok := n.endpoints[k]
|
|
|
|
+ n.Unlock()
|
|
|
|
+ if !ok {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ tmp := endpoint{}
|
|
|
|
+ if err := cs.GetObject(datastore.Key(existing.Key()...), &tmp); err != datastore.ErrKeyNotFound {
|
|
|
|
+ continue
|
|
}
|
|
}
|
|
- if c.processEndpointUpdate(&ep) {
|
|
|
|
- err = c.newEndpointFromStore(epe.Key, &ep)
|
|
|
|
- if err != nil {
|
|
|
|
- log.Error(err)
|
|
|
|
- }
|
|
|
|
|
|
+ if err := existing.deleteEndpoint(); err != nil {
|
|
|
|
+ log.Debugf("Delete failed %s: %s", existing.name, err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -245,20 +296,13 @@ func (c *controller) watchStore() error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func (c *controller) networkFromEndpointKey(key string, ep *endpoint) (Network, error) {
|
|
|
|
- nid, err := networkIDFromEndpointKey(key, ep)
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
- return c.NetworkByID(string(nid))
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func networkIDFromEndpointKey(key string, ep *endpoint) (types.UUID, error) {
|
|
|
|
- eKey, err := datastore.ParseKey(key)
|
|
|
|
- if err != nil {
|
|
|
|
- return types.UUID(""), err
|
|
|
|
|
|
+func (n *network) stopWatch() {
|
|
|
|
+ n.Lock()
|
|
|
|
+ if n.stopWatchCh != nil {
|
|
|
|
+ close(n.stopWatchCh)
|
|
|
|
+ n.stopWatchCh = nil
|
|
}
|
|
}
|
|
- return ep.networkIDFromKey(eKey)
|
|
|
|
|
|
+ n.Unlock()
|
|
}
|
|
}
|
|
|
|
|
|
func (c *controller) processEndpointUpdate(ep *endpoint) bool {
|
|
func (c *controller) processEndpointUpdate(ep *endpoint) bool {
|