From 1081687e38f8579ba34d6579aba46e7ba5366116 Mon Sep 17 00:00:00 2001 From: Madhu Venugopal Date: Fri, 2 Oct 2015 12:20:29 -0700 Subject: [PATCH] Allowing local joins to happen even when serf is not initialized With the new Discovery model, join can happen even before serf is initliazed. It could also happen due to misconfiguration of --cluster-advertise. The local endpoint join must succeed and later when the serf initializes and joins the cluster, it will push the local db to the cluster. Signed-off-by: Madhu Venugopal --- libnetwork/drivers/overlay/joinleave.go | 6 +---- libnetwork/drivers/overlay/overlay.go | 14 ++++++++++++ libnetwork/drivers/overlay/peerdb.go | 29 +++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/libnetwork/drivers/overlay/joinleave.go b/libnetwork/drivers/overlay/joinleave.go index f690492550..9fa73f1c33 100644 --- a/libnetwork/drivers/overlay/joinleave.go +++ b/libnetwork/drivers/overlay/joinleave.go @@ -75,11 +75,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, d.peerDbAdd(nid, eid, ep.addr.IP, ep.mac, net.ParseIP(d.bindAddress), true) - d.notifyCh <- ovNotify{ - action: "join", - nid: nid, - eid: eid, - } + d.pushLocalEndpointEvent("join", nid, eid) return nil } diff --git a/libnetwork/drivers/overlay/overlay.go b/libnetwork/drivers/overlay/overlay.go index c4cbbb6475..4a8a6e0137 100644 --- a/libnetwork/drivers/overlay/overlay.go +++ b/libnetwork/drivers/overlay/overlay.go @@ -174,6 +174,9 @@ func (d *driver) nodeJoin(node string, self bool) { var err error d.joinOnce.Do(func() { err = d.serfJoin(neighIP) + if err == nil { + d.pushLocalDb() + } }) if err != nil { logrus.Errorf("joining serf neighbor %s failed: %v", node, err) @@ -185,6 +188,17 @@ func (d *driver) nodeJoin(node string, self bool) { } } +func (d *driver) pushLocalEndpointEvent(action, nid, eid string) { + if !d.isSerfAlive() { + return + } + d.notifyCh <- ovNotify{ + action: "join", + nid: nid, + eid: eid, + } +} + // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster func (d *driver) DiscoverNew(dType driverapi.DiscoveryType, data interface{}) error { if dType == driverapi.NodeDiscovery { diff --git a/libnetwork/drivers/overlay/peerdb.go b/libnetwork/drivers/overlay/peerdb.go index acb99dc688..7a56009ff7 100644 --- a/libnetwork/drivers/overlay/peerdb.go +++ b/libnetwork/drivers/overlay/peerdb.go @@ -56,7 +56,23 @@ func (pKey *peerKey) Scan(state fmt.ScanState, verb rune) error { var peerDbWg sync.WaitGroup -func (d *driver) peerDbWalk(nid string, f func(*peerKey, *peerEntry) bool) error { +func (d *driver) peerDbWalk(f func(string, *peerKey, *peerEntry) bool) error { + d.peerDb.Lock() + nids := []string{} + for nid := range d.peerDb.mp { + nids = append(nids, nid) + } + d.peerDb.Unlock() + + for _, nid := range nids { + d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool { + return f(nid, pKey, pEntry) + }) + } + return nil +} + +func (d *driver) peerDbNetworkWalk(nid string, f func(*peerKey, *peerEntry) bool) error { d.peerDb.Lock() pMap, ok := d.peerDb.mp[nid] if !ok { @@ -89,7 +105,7 @@ func (d *driver) peerDbSearch(nid string, peerIP net.IP) (net.HardwareAddr, net. found bool ) - err := d.peerDbWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool { + err := d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool { if pKey.peerIP.Equal(peerIP) { peerMac = pKey.peerMac vtep = pEntry.vtep @@ -280,3 +296,12 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, return nil } + +func (d *driver) pushLocalDb() { + d.peerDbWalk(func(nid string, pKey *peerKey, pEntry *peerEntry) bool { + if pEntry.isLocal { + d.pushLocalEndpointEvent("join", nid, pEntry.eid) + } + return false + }) +}