diff --git a/prog/weaver/main.go b/prog/weaver/main.go index c9d7e9c4..e4b9ec70 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -153,7 +153,6 @@ func main() { } Log.Println("Command line options:", options()) - Log.Println("Command line peers:", peers) go check() @@ -194,9 +193,13 @@ func main() { checkFatal(err) defer db.Close() - router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlay) + router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlay, db) Log.Println("Our name is", router.Ourself) + if peers, err = router.InitialPeers(peers); err != nil { + Log.Fatal("Unable to get initial peer set: ", err) + } + var dockerCli *docker.Client if dockerAPI != "" { dc, err := docker.NewClient(dockerAPI) @@ -243,7 +246,7 @@ func main() { } router.Start() - if errors := router.ConnectionMaker.InitiateConnections(peers, false); len(errors) > 0 { + if errors := router.InitiateConnections(peers, false); len(errors) > 0 { Log.Fatal(ErrorMessages(errors)) } diff --git a/router/http.go b/router/http.go index c4057e87..90079ba7 100644 --- a/router/http.go +++ b/router/http.go @@ -14,7 +14,7 @@ func (router *NetworkRouter) HandleHTTP(muxRouter *mux.Router) { if err := r.ParseForm(); err != nil { http.Error(w, fmt.Sprint("unable to parse form: ", err), http.StatusBadRequest) } - if errors := router.ConnectionMaker.InitiateConnections(r.Form["peer"], r.FormValue("replace") == "true"); len(errors) > 0 { + if errors := router.InitiateConnections(r.Form["peer"], r.FormValue("replace") == "true"); len(errors) > 0 { http.Error(w, common.ErrorMessages(errors), http.StatusBadRequest) } }) @@ -23,7 +23,7 @@ func (router *NetworkRouter) HandleHTTP(muxRouter *mux.Router) { if err := r.ParseForm(); err != nil { http.Error(w, fmt.Sprint("unable to parse form: ", err), http.StatusBadRequest) } - router.ConnectionMaker.ForgetConnections(r.Form["peer"]) + router.ForgetConnections(r.Form["peer"]) }) } diff --git a/router/network_router.go b/router/network_router.go index f936cc04..029d9029 100644 --- a/router/network_router.go +++ b/router/network_router.go @@ -8,6 +8,7 @@ import ( "github.com/weaveworks/mesh" "github.com/weaveworks/weave/common" + "github.com/weaveworks/weave/db" ) const ( @@ -45,9 +46,10 @@ type NetworkRouter struct { *mesh.Router NetworkConfig Macs *MacCache + db db.DB } -func NewNetworkRouter(config mesh.Config, networkConfig NetworkConfig, name mesh.PeerName, nickName string, overlay NetworkOverlay) *NetworkRouter { +func NewNetworkRouter(config mesh.Config, networkConfig NetworkConfig, name mesh.PeerName, nickName string, overlay NetworkOverlay, db db.DB) *NetworkRouter { if overlay == nil { overlay = NullNetworkOverlay{} } @@ -55,7 +57,7 @@ func NewNetworkRouter(config mesh.Config, networkConfig NetworkConfig, name mesh networkConfig.Bridge = NullBridge{} } - router := &NetworkRouter{Router: mesh.NewRouter(config, name, nickName, overlay), NetworkConfig: networkConfig} + router := &NetworkRouter{Router: mesh.NewRouter(config, name, nickName, overlay), NetworkConfig: networkConfig, db: db} router.Peers.OnInvalidateShortIDs(overlay.InvalidateShortIDs) router.Routes.OnChange(overlay.InvalidateRoutes) router.Macs = NewMacCache(macMaxAge, @@ -204,3 +206,51 @@ func (router *NetworkRouter) relayBroadcast(srcPeer *mesh.Peer, key PacketKey) F return op } + +// Persisting the set of peers we are supposed to connect to +const peersIdent = "directPeers" + +func (router *NetworkRouter) persistPeers() { + if err := router.db.Save(peersIdent, router.ConnectionMaker.Targets()); err != nil { + log.Errorf("Error persisting peers: %s", err) + return + } +} + +func (router *NetworkRouter) InitiateConnections(peers []string, replace bool) []error { + errors := router.ConnectionMaker.InitiateConnections(peers, replace) + router.persistPeers() + return errors +} + +func (router *NetworkRouter) ForgetConnections(peers []string) { + router.ConnectionMaker.ForgetConnections(peers) + router.persistPeers() +} + +func (router *NetworkRouter) InitialPeers(peers []string) ([]string, error) { + var storedPeers []string + if err := router.db.Load(peersIdent, &storedPeers); err != nil { + return nil, err + } + + if storedPeers != nil && !equal(peers, storedPeers) { + log.Println("Overriding initial peer list with stored list:", storedPeers) + peers = storedPeers + } else { + log.Println("Initial set of peers:", peers) + } + return peers, nil +} + +func equal(a, b []string) bool { + if len(a) != len(b) { + return false + } + for i, v := range a { + if v != b[i] { + return false + } + } + return true +} diff --git a/test/162_persist_ipam_2_test.sh b/test/162_persist_ipam_2_test.sh index e5efac96..c4cf5151 100755 --- a/test/162_persist_ipam_2_test.sh +++ b/test/162_persist_ipam_2_test.sh @@ -14,7 +14,7 @@ launch_router_with_db() { run_on $HOST1 "sudo rm -f /tmp/test162-*" run_on $HOST2 "sudo rm -f /tmp/test162-*" -launch_router_with_db $HOST1 +launch_router_with_db $HOST1 $HOST2 launch_router_with_db $HOST2 $HOST1 start_container $HOST1 --name=c1 @@ -31,13 +31,8 @@ start_container $HOST2 --name=c3 C3=$(container_ip $HOST2 c3) assert_raises "[ $C3 != $C1 ]" -stop_router_on $HOST2 - -# Now start HOST1 with HOST2 down and see if it hangs when we launch a container -launch_router_with_db $HOST1 $HOST2 -start_container $HOST1 --name=c4 -C4=$(container_ip $HOST1 c4) -assert_raises "[ $C4 != $C1 ]" -assert_raises "[ $C4 != $C3 ]" +# Restart HOST1 and see if it remembers to connect to HOST2 +launch_router_with_db $HOST1 +assert_raises "exec_on $HOST2 c2 $PING $C1" end_suite diff --git a/vendor/github.com/weaveworks/mesh b/vendor/github.com/weaveworks/mesh index 9af1d5f8..240359e7 160000 --- a/vendor/github.com/weaveworks/mesh +++ b/vendor/github.com/weaveworks/mesh @@ -1 +1 @@ -Subproject commit 9af1d5f8b1dd29cc2c70fb7cbdd7d32b6465c34d +Subproject commit 240359e72610b8bafc7c44a9a01ade0222be4358