func NewGossipNetwork(netConf Config, executor UpdateExecutor) *Network { conf := memberlist.DefaultLocalConfig() network := &Network{ executor: executor, version: netConf.LocalVersion, } conf.BindPort = netConf.LocalPort conf.Name = netConf.Name conf.Delegate = network list, err := memberlist.Create(conf) if err != nil { panic("Failed to create memberlist: " + err.Error()) } n := 0 for i := 0; i < 3; i++ { n, err = list.Join(netConf.RootNodes) if n > 0 { break } } if n == 0 { panic("Can't connect to any of the root nodes: " + err.Error()) } network.members = list return network }
// setupAgent is used to create the agent we use func (c *Command) setupAgent(config *Config, logOutput io.Writer) *Agent { bindIP, bindPort, err := config.AddrParts(config.BindAddr) if err != nil { c.Ui.Error(fmt.Sprintf("Invalid bind address: %s", err)) return nil } var advertiseIP string var advertisePort int if config.AdvertiseAddr != "" { advertiseIP, advertisePort, err = config.AddrParts(config.AdvertiseAddr) if err != nil { c.Ui.Error(fmt.Sprintf("Invalid advertise address: %s", err)) return nil } } encryptKey, err := config.EncryptBytes() if err != nil { c.Ui.Error(fmt.Sprintf("Invalid encryption key: %s", err)) return nil } serfConfig := serf.DefaultConfig() switch config.Profile { case "lan": serfConfig.MemberlistConfig = memberlist.DefaultLANConfig() case "wan": serfConfig.MemberlistConfig = memberlist.DefaultWANConfig() case "local": serfConfig.MemberlistConfig = memberlist.DefaultLocalConfig() default: c.Ui.Error(fmt.Sprintf("Unknown profile: %s", config.Profile)) return nil } serfConfig.MemberlistConfig.BindAddr = bindIP serfConfig.MemberlistConfig.BindPort = bindPort serfConfig.MemberlistConfig.AdvertiseAddr = advertiseIP serfConfig.MemberlistConfig.AdvertisePort = advertisePort serfConfig.MemberlistConfig.SecretKey = encryptKey serfConfig.NodeName = config.NodeName serfConfig.Tags = config.Tags serfConfig.SnapshotPath = config.SnapshotPath serfConfig.ProtocolVersion = uint8(config.Protocol) serfConfig.CoalescePeriod = 3 * time.Second serfConfig.QuiescentPeriod = time.Second serfConfig.UserCoalescePeriod = 3 * time.Second serfConfig.UserQuiescentPeriod = time.Second // Start Serf c.Ui.Output("Starting Serf agent...") agent, err := Create(serfConfig, logOutput) if err != nil { c.Ui.Error(fmt.Sprintf("Failed to start the Serf agent: %v", err)) return nil } return agent }
func main() { cfg := memberlist.DefaultLocalConfig() log.Println("@bindPort:", cfg.BindPort, " @advPort:", cfg.AdvertisePort) list, err := memberlist.Create(cfg) if err != nil { panic("Failed to create memberlist: " + err.Error()) } // Join an existing cluster by specifying at least one known member.tu n, err := list.Join([]string{seedPort}) if err != nil { panic("Failed to join cluster: " + err.Error()) } log.Println("@n:", n) // Ask for members of the cluster for _, member := range list.Members() { fmt.Printf("Member: %s %s\n", member.Name, member.Addr) } time.Sleep(time.Hour * time.Duration(1)) }
func CreateMemberlistAgent(opdata *utilities.OPData, observer *Observer) *MemberlistAgent { ma := new(MemberlistAgent) fmt.Println("c1") c := memberlist.DefaultLocalConfig() fmt.Println("c3") c.Name = opdata.Name() fmt.Println("c4") c.BindAddr = opdata.Ovip c.BindPort = opdata.Serfport c.Events = observer fmt.Println("c5") list, err := memberlist.Create(c) fmt.Println("c6") if err != nil { panic("Failed to create memberlist: " + err.Error()) } ma.list = list ma.conf = c fmt.Println("MMBL created") return ma }
func CreateCluster(addr, existing string) (*Cluster, error) { host, portString, err := net.SplitHostPort(addr) if err != nil { return nil, err } port, err := strconv.Atoi(portString) if err != nil || port == 0 { return nil, errors.New("port must be defined") } config := memberlist.DefaultLocalConfig() config.BindPort = port config.AdvertisePort = port if host != "" { config.BindAddr = host } c := &Cluster{ config: config, existing: existing, LocalNodeMeta: &protobuf.NodeMeta{}, NodesByName: make(NodeMap), EdgeNodes: make(NodeMap), EntityNodes: make(NodeMap), ChunkNodes: make(ChunkNodeMap), } config.Delegate = c config.Events = c config.LogOutput = ioutil.Discard config.Name = uuid.New() return c, nil }
// Setup creates a new instance of memberlist, assigns it to list, and // sets the local nodes meta data as the rpc address. func (m *Memberlist) Setup(t *Toystore) { memberConfig := memberlist.DefaultLocalConfig() memberConfig.BindAddr = t.Host memberConfig.Name = t.Host // Set IndirectChecks to 0 so we see a local view of membership. // I.e. we don't care about nodes hidden by partitions. memberConfig.IndirectChecks = 0 // This is set really low for testing purposes. Should be ~100ms. memberConfig.GossipInterval = time.Millisecond * 20 // Sets delegate to handle membership change events. memberConfig.Events = &MemberlistEvents{t} list, err := memberlist.Create(memberConfig) if err != nil { panic(err) } m.list = list n := m.list.LocalNode() n.Meta = []byte(t.rpcAddress()) if err != nil { panic("Failed to create memberlist: " + err.Error()) } }
// setupAgent is used to create the agent we use func (c *Command) setupAgent(config *Config, logOutput io.Writer) *Agent { bindIP, bindPort, err := config.AddrParts(config.BindAddr) if err != nil { c.Ui.Error(fmt.Sprintf("Invalid bind address: %s", err)) return nil } // Check if we have an interface if iface, _ := config.NetworkInterface(); iface != nil { addrs, err := iface.Addrs() if err != nil { c.Ui.Error(fmt.Sprintf("Failed to get interface addresses: %s", err)) return nil } if len(addrs) == 0 { c.Ui.Error(fmt.Sprintf("Interface '%s' has no addresses", config.Interface)) return nil } // If there is no bind IP, pick an address if bindIP == "0.0.0.0" { found := false for _, a := range addrs { addr, ok := a.(*net.IPNet) if !ok { continue } // Skip self-assigned IPs if addr.IP.IsLinkLocalUnicast() { continue } // Found an IP found = true bindIP = addr.IP.String() c.Ui.Output(fmt.Sprintf("Using interface '%s' address '%s'", config.Interface, bindIP)) // Update the configuration bindAddr := &net.TCPAddr{ IP: net.ParseIP(bindIP), Port: bindPort, } config.BindAddr = bindAddr.String() break } if !found { c.Ui.Error(fmt.Sprintf("Failed to find usable address for interface '%s'", config.Interface)) return nil } } else { // If there is a bind IP, ensure it is available found := false for _, a := range addrs { addr, ok := a.(*net.IPNet) if !ok { continue } if addr.IP.String() == bindIP { found = true break } } if !found { c.Ui.Error(fmt.Sprintf("Interface '%s' has no '%s' address", config.Interface, bindIP)) return nil } } } var advertiseIP string var advertisePort int if config.AdvertiseAddr != "" { advertiseIP, advertisePort, err = config.AddrParts(config.AdvertiseAddr) if err != nil { c.Ui.Error(fmt.Sprintf("Invalid advertise address: %s", err)) return nil } } encryptKey, err := config.EncryptBytes() if err != nil { c.Ui.Error(fmt.Sprintf("Invalid encryption key: %s", err)) return nil } serfConfig := serf.DefaultConfig() switch config.Profile { case "lan": serfConfig.MemberlistConfig = memberlist.DefaultLANConfig() case "wan": serfConfig.MemberlistConfig = memberlist.DefaultWANConfig() case "local": serfConfig.MemberlistConfig = memberlist.DefaultLocalConfig() default: c.Ui.Error(fmt.Sprintf("Unknown profile: %s", config.Profile)) return nil } serfConfig.MemberlistConfig.BindAddr = bindIP serfConfig.MemberlistConfig.BindPort = bindPort serfConfig.MemberlistConfig.AdvertiseAddr = advertiseIP serfConfig.MemberlistConfig.AdvertisePort = advertisePort serfConfig.MemberlistConfig.SecretKey = encryptKey serfConfig.NodeName = config.NodeName serfConfig.Tags = config.Tags serfConfig.SnapshotPath = config.SnapshotPath serfConfig.ProtocolVersion = uint8(config.Protocol) serfConfig.CoalescePeriod = 3 * time.Second serfConfig.QuiescentPeriod = time.Second serfConfig.UserCoalescePeriod = 3 * time.Second serfConfig.UserQuiescentPeriod = time.Second if config.ReconnectInterval != 0 { serfConfig.ReconnectInterval = config.ReconnectInterval } if config.ReconnectTimeout != 0 { serfConfig.ReconnectTimeout = config.ReconnectTimeout } if config.TombstoneTimeout != 0 { serfConfig.TombstoneTimeout = config.TombstoneTimeout } serfConfig.EnableNameConflictResolution = !config.DisableNameResolution if config.KeyringFile != "" { serfConfig.KeyringFile = config.KeyringFile } serfConfig.RejoinAfterLeave = config.RejoinAfterLeave // Start Serf c.Ui.Output("Starting Serf agent...") agent, err := Create(config, serfConfig, logOutput) if err != nil { c.Ui.Error(fmt.Sprintf("Failed to start the Serf agent: %v", err)) return nil } return agent }
// setupAgent is used to create the agent we use func (a *AgentCommand) setupSerf(config *Config) *serf.Serf { bindIP, bindPort, err := config.AddrParts(config.BindAddr) if err != nil { a.Ui.Error(fmt.Sprintf("Invalid bind address: %s", err)) return nil } // Check if we have an interface if iface, _ := config.NetworkInterface(); iface != nil { addrs, err := iface.Addrs() if err != nil { a.Ui.Error(fmt.Sprintf("Failed to get interface addresses: %s", err)) return nil } if len(addrs) == 0 { a.Ui.Error(fmt.Sprintf("Interface '%s' has no addresses", config.Interface)) return nil } // If there is no bind IP, pick an address if bindIP == "0.0.0.0" { found := false for _, ad := range addrs { var addrIP net.IP if runtime.GOOS == "windows" { // Waiting for https://github.com/golang/go/issues/5395 to use IPNet only addr, ok := ad.(*net.IPAddr) if !ok { continue } addrIP = addr.IP } else { addr, ok := ad.(*net.IPNet) if !ok { continue } addrIP = addr.IP } // Skip self-assigned IPs if addrIP.IsLinkLocalUnicast() { continue } // Found an IP found = true bindIP = addrIP.String() a.Ui.Output(fmt.Sprintf("Using interface '%s' address '%s'", config.Interface, bindIP)) // Update the configuration bindAddr := &net.TCPAddr{ IP: net.ParseIP(bindIP), Port: bindPort, } config.BindAddr = bindAddr.String() break } if !found { a.Ui.Error(fmt.Sprintf("Failed to find usable address for interface '%s'", config.Interface)) return nil } } else { // If there is a bind IP, ensure it is available found := false for _, a := range addrs { addr, ok := a.(*net.IPNet) if !ok { continue } if addr.IP.String() == bindIP { found = true break } } if !found { a.Ui.Error(fmt.Sprintf("Interface '%s' has no '%s' address", config.Interface, bindIP)) return nil } } } var advertiseIP string var advertisePort int if config.AdvertiseAddr != "" { advertiseIP, advertisePort, err = config.AddrParts(config.AdvertiseAddr) if err != nil { a.Ui.Error(fmt.Sprintf("Invalid advertise address: %s", err)) return nil } } encryptKey, err := config.EncryptBytes() if err != nil { a.Ui.Error(fmt.Sprintf("Invalid encryption key: %s", err)) return nil } serfConfig := serf.DefaultConfig() switch config.Profile { case "lan": serfConfig.MemberlistConfig = memberlist.DefaultLANConfig() case "wan": serfConfig.MemberlistConfig = memberlist.DefaultWANConfig() case "local": serfConfig.MemberlistConfig = memberlist.DefaultLocalConfig() default: a.Ui.Error(fmt.Sprintf("Unknown profile: %s", config.Profile)) return nil } serfConfig.MemberlistConfig.BindAddr = bindIP serfConfig.MemberlistConfig.BindPort = bindPort serfConfig.MemberlistConfig.AdvertiseAddr = advertiseIP serfConfig.MemberlistConfig.AdvertisePort = advertisePort serfConfig.MemberlistConfig.SecretKey = encryptKey serfConfig.NodeName = config.NodeName serfConfig.Tags = config.Tags serfConfig.SnapshotPath = config.SnapshotPath serfConfig.CoalescePeriod = 3 * time.Second serfConfig.QuiescentPeriod = time.Second serfConfig.UserCoalescePeriod = 3 * time.Second serfConfig.UserQuiescentPeriod = time.Second if config.ReconnectInterval != 0 { serfConfig.ReconnectInterval = config.ReconnectInterval } if config.ReconnectTimeout != 0 { serfConfig.ReconnectTimeout = config.ReconnectTimeout } if config.TombstoneTimeout != 0 { serfConfig.TombstoneTimeout = config.TombstoneTimeout } serfConfig.EnableNameConflictResolution = !config.DisableNameResolution if config.KeyringFile != "" { serfConfig.KeyringFile = config.KeyringFile } serfConfig.RejoinAfterLeave = config.RejoinAfterLeave // Create a channel to listen for events from Serf a.eventCh = make(chan serf.Event, 64) serfConfig.EventCh = a.eventCh // Start Serf a.Ui.Output("Starting Serf agent...") log.Info("agent: Serf agent starting") serfConfig.LogOutput = ioutil.Discard serfConfig.MemberlistConfig.LogOutput = ioutil.Discard // Create serf first serf, err := serf.Create(serfConfig) if err != nil { a.Ui.Error(err.Error()) log.Error(err) return nil } return serf }
func NewRegistry(opts ...registry.Option) registry.Registry { var options registry.Options for _, o := range opts { o(&options) } cAddrs := []string{} hostname, _ := os.Hostname() updates := make(chan *update, 100) for _, addr := range options.Addrs { if len(addr) > 0 { cAddrs = append(cAddrs, addr) } } broadcasts := &memberlist.TransmitLimitedQueue{ NumNodes: func() int { return len(cAddrs) }, RetransmitMult: 3, } mr := &gossipRegistry{ broadcasts: broadcasts, services: make(map[string][]*registry.Service), updates: updates, subs: make(map[string]chan *registry.Result), } go mr.run() c := memberlist.DefaultLocalConfig() c.BindPort = 0 c.Name = hostname + "-" + uuid.NewUUID().String() c.Delegate = &delegate{ updates: updates, broadcasts: broadcasts, } if options.Secure { k, ok := options.Context.Value(contextSecretKey{}).([]byte) if !ok { k = DefaultKey } c.SecretKey = k } m, err := memberlist.Create(c) if err != nil { log.Fatalf("Error creating memberlist: %v", err) } if len(cAddrs) > 0 { _, err := m.Join(cAddrs) if err != nil { log.Fatalf("Error joining members: %v", err) } } log.Printf("Local memberlist node %s:%d\n", m.LocalNode().Addr, m.LocalNode().Port) return mr }
func main() { flag.Parse() log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) /* Create the initial memberlist from a safe configuration. Please reference the godoc for other default config types. http://godoc.org/github.com/hashicorp/memberlist#Config */ evtDelegate := MultiEventDelegate{} var delegate = NewDelegate(*name, *tcpport) var cfg = memberlist.DefaultLocalConfig() cfg.Events = &evtDelegate cfg.Delegate = delegate cfg.Name = *name cfg.BindPort = *port cfg.BindAddr = *addr cfg.AdvertisePort = *port cfg.AdvertiseAddr = *addr list, err := memberlist.Create(cfg) if err != nil { log.Fatalln("Failed to create memberlist: " + err.Error()) return } if len(*hosts) > 0 { // Join an existing cluster by specifying at least one known member. _, err = list.Join(strings.Split(*hosts, ",")) if err != nil { log.Println("Failed to join cluster: " + err.Error()) } } // Ask for members of the cluster for _, member := range list.Members() { fmt.Printf("Member: %s %s\n", member.Name, member.Addr) } lookup := NewNodeLookup() transport := NewTcpTransporter() // Setup raft id := uint32(Jesteress([]byte(cfg.Name))) log.Printf("Name: %s ID: %d", cfg.Name, id) storage := raft.NewMemoryStorage() c := &raft.Config{ ID: uint64(id), ElectionTick: 10, HeartbeatTick: 1, Storage: storage, MaxSizePerMsg: 4096, MaxInflightMsgs: 256, } log.Println("Node ID: ", c.ID) r := NewRaftNode(*name, c, storage, lookup, transport) evtDelegate.AddEventDelegate(r) // Listen for incoming connections. l, err := net.Listen("tcp", fmt.Sprintf(":%d", *tcpport)) if err != nil { log.Println("Error listening:", err.Error()) return } // Start TCP server server := TCPServer{l, r} go server.Start() fmt.Printf("Listening on %s:%d\n", *tcpaddr, *tcpport) // Close the listener when the application closes. defer server.Stop() // Start raft server go r.Start() // Handle signals sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, os.Kill) // Wait for signal log.Println("Cluster open for business") // Block until signal is received <-sig log.Println("Shutting down node") if err = list.Leave(time.Second); err != nil { log.Println("Error leaving cluster: " + err.Error()) } if err = list.Shutdown(); err != nil { log.Println("Error shutting down node: " + err.Error()) } }