Exemple #1
0
// DefaultConfig is used to return a sane default configuration
func DefaultConfig() *Config {
	hostname, err := os.Hostname()
	if err != nil {
		panic(err)
	}

	conf := &Config{
		Datacenter:        DefaultDC,
		NodeName:          hostname,
		RPCAddr:           DefaultRPCAddr,
		RaftConfig:        raft.DefaultConfig(),
		SerfLANConfig:     serf.DefaultConfig(),
		SerfWANConfig:     serf.DefaultConfig(),
		ReconcileInterval: 60 * time.Second,
		ProtocolVersion:   ProtocolVersionMax,
	}

	// Increase our reap interval to 3 days instead of 24h.
	conf.SerfLANConfig.ReconnectTimeout = 3 * 24 * time.Hour
	conf.SerfWANConfig.ReconnectTimeout = 3 * 24 * time.Hour

	// WAN Serf should use the WAN timing, since we are using it
	// to communicate between DC's
	conf.SerfWANConfig.MemberlistConfig = memberlist.DefaultWANConfig()

	// Ensure we don't have port conflicts
	conf.SerfLANConfig.MemberlistConfig.BindPort = DefaultLANSerfPort
	conf.SerfWANConfig.MemberlistConfig.BindPort = DefaultWANSerfPort

	// Disable shutdown on removal
	conf.RaftConfig.ShutdownOnRemove = false

	return conf
}
Exemple #2
0
// DefaultConfig is used to return a sane default configuration
func DefaultConfig() *Config {
	hostname, err := os.Hostname()
	if err != nil {
		panic(err)
	}

	conf := &Config{
		Datacenter:               DefaultDC,
		NodeName:                 hostname,
		RPCAddr:                  DefaultRPCAddr,
		RaftConfig:               raft.DefaultConfig(),
		SerfLANConfig:            serf.DefaultConfig(),
		SerfWANConfig:            serf.DefaultConfig(),
		ReconcileInterval:        60 * time.Second,
		ProtocolVersion:          ProtocolVersion2Compatible,
		ACLTTL:                   30 * time.Second,
		ACLDefaultPolicy:         "allow",
		ACLDownPolicy:            "extend-cache",
		ACLReplicationInterval:   30 * time.Second,
		ACLReplicationApplyLimit: 100, // ops / sec
		TombstoneTTL:             15 * time.Minute,
		TombstoneTTLGranularity:  30 * time.Second,
		SessionTTLMin:            10 * time.Second,
		DisableCoordinates:       false,

		// These are tuned to provide a total throughput of 128 updates
		// per second. If you update these, you should update the client-
		// side SyncCoordinateRateTarget parameter accordingly.
		CoordinateUpdatePeriod:     5 * time.Second,
		CoordinateUpdateBatchSize:  128,
		CoordinateUpdateMaxBatches: 5,

		// Hold an RPC for up to 5 seconds by default
		RPCHoldTimeout: 5 * time.Second,
	}

	// Increase our reap interval to 3 days instead of 24h.
	conf.SerfLANConfig.ReconnectTimeout = 3 * 24 * time.Hour
	conf.SerfWANConfig.ReconnectTimeout = 3 * 24 * time.Hour

	// WAN Serf should use the WAN timing, since we are using it
	// to communicate between DC's
	conf.SerfWANConfig.MemberlistConfig = memberlist.DefaultWANConfig()

	// Ensure we don't have port conflicts
	conf.SerfLANConfig.MemberlistConfig.BindPort = DefaultLANSerfPort
	conf.SerfWANConfig.MemberlistConfig.BindPort = DefaultWANSerfPort

	// Enable interoperability with unversioned Raft library, and don't
	// start using new ID-based features yet.
	conf.RaftConfig.ProtocolVersion = 1

	// Disable shutdown on removal
	conf.RaftConfig.ShutdownOnRemove = false

	return conf
}
Exemple #3
0
// DefaultConfig is used to return a sane default configuration
func DefaultConfig() *Config {
	hostname, err := os.Hostname()
	if err != nil {
		panic(err)
	}

	conf := &Config{
		Datacenter:              DefaultDC,
		NodeName:                hostname,
		RPCAddr:                 DefaultRPCAddr,
		RaftConfig:              raft.DefaultConfig(),
		SerfLANConfig:           serf.DefaultConfig(),
		SerfWANConfig:           serf.DefaultConfig(),
		ReconcileInterval:       60 * time.Second,
		ProtocolVersion:         ProtocolVersion2Compatible,
		ACLTTL:                  30 * time.Second,
		ACLDefaultPolicy:        "allow",
		ACLDownPolicy:           "extend-cache",
		TombstoneTTL:            15 * time.Minute,
		TombstoneTTLGranularity: 30 * time.Second,
		SessionTTLMin:           10 * time.Second,
		DisableCoordinates:      false,

		// These are tuned to provide a total throughput of 128 updates
		// per second. If you update these, you should update the client-
		// side SyncCoordinateRateTarget parameter accordingly.
		CoordinateUpdatePeriod:     5 * time.Second,
		CoordinateUpdateBatchSize:  128,
		CoordinateUpdateMaxBatches: 5,
	}

	// Increase our reap interval to 3 days instead of 24h.
	conf.SerfLANConfig.ReconnectTimeout = 3 * 24 * time.Hour
	conf.SerfWANConfig.ReconnectTimeout = 3 * 24 * time.Hour

	// WAN Serf should use the WAN timing, since we are using it
	// to communicate between DC's
	conf.SerfWANConfig.MemberlistConfig = memberlist.DefaultWANConfig()

	// Turn LAN Serf to run globally
	conf.SerfLANConfig.MemberlistConfig = memberlist.DefaultWANConfig()

	// Ensure we don't have port conflicts
	conf.SerfLANConfig.MemberlistConfig.BindPort = DefaultLANSerfPort
	conf.SerfWANConfig.MemberlistConfig.BindPort = DefaultWANSerfPort

	// Disable shutdown on removal
	conf.RaftConfig.ShutdownOnRemove = false

	// Make Raft more WAN friendly
	conf.RaftConfig.HeartbeatTimeout = 5000 * time.Millisecond
	conf.RaftConfig.ElectionTimeout = 5000 * time.Millisecond
	conf.RaftConfig.CommitTimeout = 100 * time.Millisecond
	conf.RaftConfig.LeaderLeaseTimeout = 2500 * time.Millisecond

	return conf
}
Exemple #4
0
func TestAgentTagsFile(t *testing.T) {
	tags := map[string]string{
		"role":       "webserver",
		"datacenter": "us-east",
	}

	td, err := ioutil.TempDir("", "serf")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(td)

	agentConfig := DefaultConfig()
	agentConfig.TagsFile = filepath.Join(td, "tags.json")

	a1 := testAgentWithConfig(agentConfig, serf.DefaultConfig(), nil)

	if err := a1.Start(); err != nil {
		t.Fatalf("err: %s", err)
	}
	defer a1.Shutdown()
	defer a1.Leave()

	testutil.Yield()

	err = a1.SetTags(tags)

	if err != nil {
		t.Fatalf("err: %s", err)
	}

	testutil.Yield()

	a2 := testAgentWithConfig(agentConfig, serf.DefaultConfig(), nil)

	if err := a2.Start(); err != nil {
		t.Fatalf("err: %s", err)
	}
	defer a2.Shutdown()
	defer a2.Leave()

	testutil.Yield()

	m := a2.Serf().LocalMember()

	if !reflect.DeepEqual(m.Tags, tags) {
		t.Fatalf("tags not restored: %#v", m.Tags)
	}
}
Exemple #5
0
func Create() (*Agent, error) {
	conf := serf.DefaultConfig()
	conf.Init()
	conf.NodeName = os.Getenv("HOST")
	conf.Tags["DOCKER_HOST"] = Os.Getenv("DOCKER_HOST")

	logOutput := log.StandardLogger().Out

	// Setup the underlying loggers
	conf.MemberlistConfig.LogOutput = logOutput
	conf.LogOutput = logOutput

	// Create a channel to listen for events from Serf
	eventCh := make(chan serf.Event, 64)
	conf.EventCh = eventCh

	// support only LAN configuration at the moment
	conf.MemberlistConfig = memberlist.DefaultLANConfig()
	conf.MemberlistConfig.BindAddr = "0.0.0.0"
	conf.MemberlistConfig.BindPort = 3388

	// Setup the agent
	agent := &Agent{
		conf:       conf,
		eventCh:    eventCh,
		isManager:  false,
		shutdownCh: make(chan struct{}),
	}

	return agent, nil
}
Exemple #6
0
func (a *Agent) Start() error {
	conf := serf.DefaultConfig()
	conf.Init()
	conf.Tags["role"] = "agent"
	conf.Tags["info"] = a.getInfo()

	bindAddr, err := a.config.GetIpByInterface()
	if err != nil {
		log.Fatal(err)
	}

	conf.NodeName = a.config.Name

	conf.MemberlistConfig.BindAddr = bindAddr
	conf.EventCh = a.eventCh

	serf, err := serf.Create(conf)
	if err != nil {
		return err
	}

	a.serf = serf

	go a.handleEvents()

	return nil
}
Exemple #7
0
func (n *Node) createSerfAgent(iface string) {

	serfConfig := serf.DefaultConfig()

	serfConfig.Tags = n.tags

	serfConfig.MemberlistConfig.BindAddr = iface
	serfConfig.MemberlistConfig.BindPort = getRandomPort(iface)

	serfConfig.NodeName = fmt.Sprintf("%s@%s", n.UUID, iface)
	serfConfig.Tags = n.tags
	serfConfig.LogOutput = ioutil.Discard
	//	serfConfig.MemberlistConfig.GossipInterval = 5 * time.Millisecond
	//	serfConfig.MemberlistConfig.ProbeInterval = 50 * time.Millisecond
	//	serfConfig.MemberlistConfig.ProbeTimeout = 25 * time.Millisecond
	//	serfConfig.MemberlistConfig.SuspicionMult = 1
	serfConfig.Init()
	agentConfig := agent.DefaultConfig()
	agentConfig.Tags = n.tags
	agentConfig.LogLevel = "INFO"
	agt, err := agent.Create(agentConfig, serfConfig, ioutil.Discard)
	//	agt, err := agent.Create(agentConfig, serfConfig, n.cfg.Logger())

	if n.handleErr(err) {
		eventHandler := newEventHandler()
		n.join.Join(eventHandler.join.WhereNot(n.isSelf))
		n.leave.Join(eventHandler.leave.WhereNot(n.isSelf).Transform(toLeaveEvent()))
		n.query.Join(eventHandler.query.Transform(toQueryEvent(iface)))
		agt.RegisterEventHandler(eventHandler)
		n.agents[iface] = agt
		n.logger.Println("Agent Created On Port", agt.SerfConfig().MemberlistConfig.BindPort)
	} else {
		n.logger.Println("Failed to create Agent")
	}
}
Exemple #8
0
func main() {
	InitLogger(logrus.DebugLevel.String(), "yws1")

	serfConfig := serf.DefaultConfig()
	serfConfig.NodeName = "yws1"
	serfConfig.MemberlistConfig = memberlist.DefaultLANConfig()

	serfConfig.MemberlistConfig.BindAddr = "127.0.0.1"
	serfConfig.MemberlistConfig.BindPort = 7373
	serfConfig.MemberlistConfig.AdvertiseAddr = "127.0.0.1"
	serfConfig.MemberlistConfig.AdvertisePort = 5000

	eventCh := make(chan serf.Event, 64)
	serfConfig.EventCh = eventCh
	serfConfig.LogOutput = ioutil.Discard
	serfConfig.MemberlistConfig.LogOutput = ioutil.Discard

	s, err := serf.Create(serfConfig)
	if err != nil {
		fmt.Println(err)
	}

	go func() {
		serfShutdownCh := s.ShutdownCh()
		log.Info("agent: Listen for events")
		for {
			select {
			case e := <-eventCh:
				log.WithFields(logrus.Fields{
					"event": e.String(),
				}).Debug("agent: Received event")

				// Log all member events
				if failed, ok := e.(serf.MemberEvent); ok {
					for _, member := range failed.Members {
						log.WithFields(logrus.Fields{
							"node":   "yang",
							"member": member.Name,
							"event":  e.EventType(),
						}).Debug("agent: Member event")
					}
				}

				if e.EventType() == serf.EventQuery {
					query := e.(*serf.Query)
					fmt.Println(query)
				}

			case <-serfShutdownCh:
				log.Warn("agent: Serf shutdown detected, quitting")
				return
			}
		}
	}()

	fmt.Println(s)

	wait := make(chan int)
	<-wait
}
Exemple #9
0
func (d *driver) serfInit() error {
	var err error

	config := serf.DefaultConfig()
	config.Init()
	config.MemberlistConfig.BindAddr = d.bindAddress

	d.eventCh = make(chan serf.Event, 4)
	config.EventCh = d.eventCh
	config.UserCoalescePeriod = 1 * time.Second
	config.UserQuiescentPeriod = 50 * time.Millisecond

	config.LogOutput = &logWriter{}
	config.MemberlistConfig.LogOutput = config.LogOutput

	s, err := serf.Create(config)
	if err != nil {
		return fmt.Errorf("failed to create cluster node: %v", err)
	}
	defer func() {
		if err != nil {
			s.Shutdown()
		}
	}()

	d.serfInstance = s

	d.notifyCh = make(chan ovNotify)
	d.exitCh = make(chan chan struct{})

	go d.startSerfLoop(d.eventCh, d.notifyCh, d.exitCh)
	return nil
}
Exemple #10
0
// 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
}
Exemple #11
0
// DefaultNodeConfig returns a reasonable default to use.
func DefaultNodeConfig() *NodeConfig {
	return &NodeConfig{
		Replicas:       2,
		RpcPort:        11211,
		SerfConfig:     serf.DefaultConfig(),
		MaxMemoryUsage: 1 << 30, // 1 GB
	}
}
Exemple #12
0
// DefaultConfig returns the default configuration
func DefaultConfig() *Config {
	hostname, err := os.Hostname()
	if err != nil {
		panic(err)
	}

	c := &Config{
		Region:                 DefaultRegion,
		Datacenter:             DefaultDC,
		NodeName:               hostname,
		ProtocolVersion:        ProtocolVersionMax,
		RaftConfig:             raft.DefaultConfig(),
		RaftTimeout:            10 * time.Second,
		LogOutput:              os.Stderr,
		RPCAddr:                DefaultRPCAddr,
		SerfConfig:             serf.DefaultConfig(),
		NumSchedulers:          1,
		ReconcileInterval:      60 * time.Second,
		EvalGCInterval:         5 * time.Minute,
		EvalGCThreshold:        1 * time.Hour,
		JobGCInterval:          5 * time.Minute,
		JobGCThreshold:         4 * time.Hour,
		NodeGCInterval:         5 * time.Minute,
		NodeGCThreshold:        24 * time.Hour,
		EvalNackTimeout:        60 * time.Second,
		EvalDeliveryLimit:      3,
		MinHeartbeatTTL:        10 * time.Second,
		MaxHeartbeatsPerSecond: 50.0,
		HeartbeatGrace:         10 * time.Second,
		FailoverHeartbeatTTL:   300 * time.Second,
		ConsulConfig:           config.DefaultConsulConfig(),
		VaultConfig:            config.DefaultVaultConfig(),
		RPCHoldTimeout:         5 * time.Second,
		TLSConfig:              &config.TLSConfig{},
	}

	// Enable all known schedulers by default
	c.EnabledSchedulers = make([]string, 0, len(scheduler.BuiltinSchedulers))
	for name := range scheduler.BuiltinSchedulers {
		c.EnabledSchedulers = append(c.EnabledSchedulers, name)
	}
	c.EnabledSchedulers = append(c.EnabledSchedulers, structs.JobTypeCore)

	// Default the number of schedulers to match the coores
	c.NumSchedulers = runtime.NumCPU()

	// Increase our reap interval to 3 days instead of 24h.
	c.SerfConfig.ReconnectTimeout = 3 * 24 * time.Hour

	// Serf should use the WAN timing, since we are using it
	// to communicate between DC's
	c.SerfConfig.MemberlistConfig = memberlist.DefaultWANConfig()
	c.SerfConfig.MemberlistConfig.BindPort = DefaultSerfPort

	// Disable shutdown on removal
	c.RaftConfig.ShutdownOnRemove = false
	return c
}
Exemple #13
0
func serfInit() *serf.Serf {
	conf := serf.DefaultConfig()
	serfin, err := serf.Create(conf)
	if err != nil {
		log.Fatal(err)
	}

	return serfin
}
func TestAgentKeyringFile_BadOptions(t *testing.T) {
	agentConfig := DefaultConfig()
	agentConfig.KeyringFile = "/some/path"
	agentConfig.EncryptKey = "pL4owv4IE1x+ZXCyd5vLLg=="

	_, err := Create(agentConfig, serf.DefaultConfig(), nil)
	if err == nil || !strings.Contains(err.Error(), "not allowed") {
		t.Fatalf("err: %s", err)
	}
}
Exemple #15
0
// DefaultConfig returns a Config with sane default values.
func DefaultConfig() Config {
	return Config{
		Partitions: 512,
		Redundancy: 3,
		SerfConfig: serf.DefaultConfig(),
		Events:     make(chan Event),
		LogOutput:  os.Stderr,
		LogLevel:   2,
	}
}
Exemple #16
0
func TestAgentTagsFile_BadOptions(t *testing.T) {
	agentConfig := DefaultConfig()
	agentConfig.TagsFile = "/some/path"
	agentConfig.Tags = map[string]string{
		"tag1": "val1",
	}

	_, err := Create(agentConfig, serf.DefaultConfig(), nil)
	if err == nil || !strings.Contains(err.Error(), "not allowed") {
		t.Fatalf("err: %s", err)
	}
}
Exemple #17
0
func testAgent() *Agent {
	config := serf.DefaultConfig()
	config.MemberlistConfig.BindAddr = testutil.GetBindAddr().String()
	config.NodeName = config.MemberlistConfig.BindAddr

	agent := &Agent{
		RPCAddr:    getRPCAddr(),
		SerfConfig: config,
	}

	return agent
}
Exemple #18
0
func (s *Server) setupSerf() (*serf.Serf, error) {
	conf := serf.DefaultConfig()

	// Generate NodeName if missing
	id, err := uuid.UUID4()
	if err != nil {
		return nil, err
	}

	// Get SSH server port
	port := s.sshServer.Addr.Port

	// Initialize serf
	conf.Init()
	// s.logger.Info("local port", "port", conf.MemberlistConfig.BindPort)

	conf.NodeName = s.config.NodeName
	conf.MemberlistConfig.BindAddr = s.config.GossipBindAddr
	conf.MemberlistConfig.BindPort = s.config.GossipBindPort
	conf.MemberlistConfig.AdvertiseAddr = s.config.GossipAdvertiseAddr
	conf.MemberlistConfig.AdvertisePort = s.config.GossipAdvertisePort
	s.logger.Info("Gossip", "BindAddr", conf.MemberlistConfig.BindAddr, "BindPort", conf.MemberlistConfig.BindPort, "AdvertiseAddr", conf.MemberlistConfig.AdvertiseAddr, "AdvertisePort", conf.MemberlistConfig.AdvertisePort)

	conf.Tags["id"] = id
	conf.Tags["role"] = "kappa-server"
	conf.Tags["cluster"] = s.config.ClusterName
	conf.Tags["build"] = s.config.Build
	conf.Tags["port"] = fmt.Sprintf("%d", port)
	if s.config.Bootstrap {
		conf.Tags["bootstrap"] = "1"
	}
	if s.config.BootstrapExpect != 0 {
		conf.Tags["expect"] = fmt.Sprintf("%d", s.config.BootstrapExpect)
	}

	conf.MemberlistConfig.LogOutput = s.config.LogOutput
	conf.LogOutput = s.config.LogOutput
	conf.EventCh = s.serfEventCh
	conf.SnapshotPath = filepath.Join(s.config.DataPath, serfSnapshot)
	conf.ProtocolVersion = conf.ProtocolVersion
	conf.RejoinAfterLeave = true
	conf.EnableNameConflictResolution = false

	conf.Merge = &mergeDelegate{name: s.config.ClusterName}
	if err := ensurePath(conf.SnapshotPath, false); err != nil {
		return nil, err
	}
	return serf.Create(conf)
}
Exemple #19
0
func testAgent(logOutput io.Writer) *Agent {
	if logOutput == nil {
		logOutput = os.Stderr
	}
	config := serf.DefaultConfig()
	config.MemberlistConfig.ProbeInterval = 100 * time.Millisecond
	config.MemberlistConfig.BindAddr = testutil.GetBindAddr().String()
	config.NodeName = config.MemberlistConfig.BindAddr

	agent, err := Create(config, logOutput)
	if err != nil {
		panic(err)
	}
	return agent
}
Exemple #20
0
func testAgent(t *testing.T) *agent.Agent {
	config := serf.DefaultConfig()
	config.MemberlistConfig.BindAddr = testutil.GetBindAddr().String()
	config.NodeName = config.MemberlistConfig.BindAddr

	agent := &agent.Agent{
		RPCAddr:    getRPCAddr(),
		SerfConfig: config,
	}

	if err := agent.Start(); err != nil {
		t.Fatalf("err: %s", err)
	}

	return agent
}
func (d *driver) serfInit() error {
	var err error

	config := serf.DefaultConfig()
	config.Init()
	if d.ifaceName != "" {
		bindAddr, err := getBindAddr(d.ifaceName)
		if err != nil {
			return fmt.Errorf("getBindAddr error: %v", err)
		}
		config.MemberlistConfig.BindAddr = bindAddr
	}

	d.eventCh = make(chan serf.Event, 4)
	config.EventCh = d.eventCh
	config.UserCoalescePeriod = 1 * time.Second
	config.UserQuiescentPeriod = 50 * time.Millisecond

	config.LogOutput = logrus.StandardLogger().Out

	s, err := serf.Create(config)
	if err != nil {
		return fmt.Errorf("failed to create cluster node: %v", err)
	}
	defer func() {
		if err != nil {
			s.Shutdown()
		}
	}()

	if d.neighIP != "" {
		if _, err = s.Join([]string{d.neighIP}, false); err != nil {
			return fmt.Errorf("Failed to join the cluster at neigh IP %s: %v",
				d.neighIP, err)
		}
	}

	d.serfInstance = s

	d.notifyCh = make(chan ovNotify)
	d.exitCh = make(chan chan struct{})

	go d.startSerfLoop(d.eventCh, d.notifyCh, d.exitCh)
	return nil
}
Exemple #22
0
func testAgent(t *testing.T) *agent.Agent {
	config := serf.DefaultConfig()
	config.MemberlistConfig.BindAddr = testutil.GetBindAddr().String()
	config.MemberlistConfig.ProbeInterval = 50 * time.Millisecond
	config.MemberlistConfig.ProbeTimeout = 25 * time.Millisecond
	config.MemberlistConfig.SuspicionMult = 1
	config.NodeName = config.MemberlistConfig.BindAddr

	agent := &agent.Agent{
		RPCAddr:    getRPCAddr(),
		SerfConfig: config,
	}

	if err := agent.Start(); err != nil {
		t.Fatalf("err: %s", err)
	}

	return agent
}
func TestAgentKeyringFile(t *testing.T) {
	keys := []string{
		"enjTwAFRe4IE71bOFhirzQ==",
		"csT9mxI7aTf9ap3HLBbdmA==",
		"noha2tVc0OyD/2LtCBoAOQ==",
	}

	td, err := ioutil.TempDir("", "serf")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(td)

	keyringFile := filepath.Join(td, "keyring.json")

	serfConfig := serf.DefaultConfig()
	agentConfig := DefaultConfig()
	agentConfig.KeyringFile = keyringFile

	encodedKeys, err := json.Marshal(keys)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	if err := ioutil.WriteFile(keyringFile, encodedKeys, 0600); err != nil {
		t.Fatalf("err: %s", err)
	}

	a1 := testAgentWithConfig(agentConfig, serfConfig, nil)

	if err := a1.Start(); err != nil {
		t.Fatalf("err: %s", err)
	}
	defer a1.Shutdown()

	testutil.Yield()

	totalLoadedKeys := len(serfConfig.MemberlistConfig.Keyring.GetKeys())
	if totalLoadedKeys != 3 {
		t.Fatalf("Expected to load 3 keys but got %d", totalLoadedKeys)
	}
}
func testAgent(t *testing.T) *agent.Agent {
	config := serf.DefaultConfig()
	config.MemberlistConfig.BindAddr = testutil.GetBindAddr().String()
	config.MemberlistConfig.ProbeInterval = 50 * time.Millisecond
	config.MemberlistConfig.ProbeTimeout = 25 * time.Millisecond
	config.MemberlistConfig.SuspicionMult = 1
	config.NodeName = config.MemberlistConfig.BindAddr
	config.Tags = map[string]string{"role": "test", "tag1": "foo", "tag2": "bar"}

	agent, err := agent.Create(config, nil)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	if err := agent.Start(); err != nil {
		t.Fatalf("err: %s", err)
	}

	return agent
}
Exemple #25
0
func testKeysCommandAgent(t *testing.T) *agent.Agent {
	key1, err := base64.StdEncoding.DecodeString("SNCg1bQSoCdGVlEx+TgfBw==")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	key2, err := base64.StdEncoding.DecodeString("vbitCcJNwNP4aEWHgofjMg==")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	keyring, err := memberlist.NewKeyring([][]byte{key1, key2}, key1)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	agentConf := agent.DefaultConfig()
	serfConf := serf.DefaultConfig()
	serfConf.MemberlistConfig.Keyring = keyring

	a1 := testAgentWithConfig(t, agentConf, serfConf)
	return a1
}
Exemple #26
0
func DefaultConfig() (*Config, error) {
	hostname, err := os.Hostname()
	if err != nil {
		return nil, err
	}
	ambariConfig, err := DefaultAmbariConfig()
	if err != nil {
		return nil, err
	}
	c := &Config{
		NodeName:     hostname,
		SerfConfig:   serf.DefaultConfig(),
		RPCAddr:      DefaultRPCAddr,
		AmbariConfig: ambariConfig,
		HostsFile:    "/etc/hosts",

		HostsUpdateInterval: 10 * time.Second,
	}
	c.setupSerfConfig()
	return c, nil
}
Exemple #27
0
func TestAgentKeyringFile_NoKeys(t *testing.T) {
	dir, err := ioutil.TempDir("", "serf")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(dir)

	keysFile := filepath.Join(dir, "keyring")
	if err := ioutil.WriteFile(keysFile, []byte("[]"), 0600); err != nil {
		t.Fatalf("err: %s", err)
	}

	agentConfig := DefaultConfig()
	agentConfig.KeyringFile = keysFile

	_, err = Create(agentConfig, serf.DefaultConfig(), nil)
	if err == nil {
		t.Fatalf("should have errored")
	}
	if !strings.Contains(err.Error(), "contains no keys") {
		t.Fatalf("bad: %s", err)
	}
}
Exemple #28
0
func (c *cerebrum) setupSerf() (*serf.Serf, error) {
	// Get serf config
	conf := serf.DefaultConfig()

	// Initialize serf
	conf.Init()

	conf.NodeName = c.config.NodeName
	conf.MemberlistConfig.BindAddr = c.config.GossipBindAddr
	conf.MemberlistConfig.BindPort = c.config.GossipBindPort
	conf.MemberlistConfig.AdvertiseAddr = c.config.GossipAdvertiseAddr
	conf.MemberlistConfig.AdvertisePort = c.config.GossipAdvertisePort
	c.logger.Info("Gossip",
		"BindAddr", conf.MemberlistConfig.BindAddr,
		"BindPort", conf.MemberlistConfig.BindPort,
		"AdvertiseAddr", conf.MemberlistConfig.AdvertiseAddr,
		"AdvertisePort", conf.MemberlistConfig.AdvertisePort)

	conf.Tags["id"] = c.config.NodeID
	conf.Tags["role"] = "cerebrum-server"
	conf.Tags["dc"] = c.config.DataCenter
	// conf.Tags["port"] = fmt.Sprintf("%d", port)

	conf.MemberlistConfig.LogOutput = c.config.LogOutput
	conf.LogOutput = c.config.LogOutput
	conf.EventCh = c.serfEventCh
	conf.SnapshotPath = filepath.Join(c.config.DataPath, SerfSnapshotDir)
	conf.ProtocolVersion = conf.ProtocolVersion
	conf.RejoinAfterLeave = true
	conf.EnableNameConflictResolution = false
	conf.Merge = &mergeDelegate{c.logger}
	if err := os.MkdirAll(conf.SnapshotPath, 0755); err != nil {
		return nil, err
	}
	return serf.Create(conf)
}
Exemple #29
0
func (c *Command) Run(args []string) int {
	ui := &cli.PrefixedUi{
		OutputPrefix: "==> ",
		InfoPrefix:   "    ",
		ErrorPrefix:  "==> ",
		Ui:           c.Ui,
	}

	var cmdConfig Config
	var configFiles []string

	cmdFlags := flag.NewFlagSet("agent", flag.ContinueOnError)
	cmdFlags.Usage = func() { ui.Output(c.Help()) }
	cmdFlags.StringVar(&cmdConfig.BindAddr, "bind", "", "address to bind listeners to")
	cmdFlags.Var((*AppendSliceValue)(&configFiles), "config-file",
		"json file to read config from")
	cmdFlags.Var((*AppendSliceValue)(&configFiles), "config-dir",
		"directory of json files to read")
	cmdFlags.StringVar(&cmdConfig.EncryptKey, "encrypt", "", "encryption key")
	cmdFlags.Var((*AppendSliceValue)(&cmdConfig.EventHandlers), "event-handler",
		"command to execute when events occur")
	cmdFlags.Var((*AppendSliceValue)(&cmdConfig.StartJoin), "join",
		"address of agent to join on startup")
	cmdFlags.StringVar(&cmdConfig.LogLevel, "log-level", "", "log level")
	cmdFlags.StringVar(&cmdConfig.NodeName, "node", "", "node name")
	cmdFlags.IntVar(&cmdConfig.Protocol, "protocol", -1, "protocol version")
	cmdFlags.StringVar(&cmdConfig.Role, "role", "", "role name")
	cmdFlags.StringVar(&cmdConfig.RPCAddr, "rpc-addr", "",
		"address to bind RPC listener to")
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	config := DefaultConfig
	if len(configFiles) > 0 {
		fileConfig, err := ReadConfigPaths(configFiles)
		if err != nil {
			c.Ui.Error(err.Error())
			return 1
		}

		config = MergeConfig(config, fileConfig)
	}

	config = MergeConfig(config, &cmdConfig)

	if config.NodeName == "" {
		hostname, err := os.Hostname()
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Error determining hostname: %s", err))
			return 1
		}

		config.NodeName = hostname
	}

	eventScripts, err := config.EventScripts()
	if err != nil {
		c.Ui.Error(err.Error())
		return 1
	}

	for _, script := range eventScripts {
		if !script.Valid() {
			c.Ui.Error(fmt.Sprintf("Invalid event script: %s", script.String()))
			return 1
		}
	}

	bindIP, bindPort, err := config.BindAddrParts()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Invalid bind address: %s", err))
		return 1
	}

	encryptKey, err := config.EncryptBytes()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Invalid encryption key: %s", err))
		return 1
	}

	// Setup logging. First create the gated log writer, which will
	// store logs until we're ready to show them. Then create the level
	// filter, filtering logs of the specified level.
	logGate := &GatedWriter{
		Writer: &cli.UiWriter{Ui: c.Ui},
	}

	logLevelFilter := LevelFilter()
	logLevelFilter.MinLevel = logutils.LogLevel(strings.ToUpper(config.LogLevel))
	logLevelFilter.Writer = logGate
	if !ValidateLevelFilter(logLevelFilter) {
		ui.Error(fmt.Sprintf(
			"Invalid log level: %s. Valid log levels are: %v",
			logLevelFilter.MinLevel, logLevelFilter.Levels))
		return 1
	}

	serfConfig := serf.DefaultConfig()
	serfConfig.MemberlistConfig.BindAddr = bindIP
	serfConfig.MemberlistConfig.Port = bindPort
	serfConfig.MemberlistConfig.SecretKey = encryptKey
	serfConfig.NodeName = config.NodeName
	serfConfig.Role = config.Role
	serfConfig.ProtocolVersion = uint8(config.Protocol)
	serfConfig.CoalescePeriod = 3 * time.Second
	serfConfig.QuiescentPeriod = time.Second
	serfConfig.UserCoalescePeriod = 3 * time.Second
	serfConfig.UserQuiescentPeriod = time.Second

	agent := &Agent{
		EventHandler: &ScriptEventHandler{
			Self: serf.Member{
				Name: serfConfig.NodeName,
				Role: serfConfig.Role,
			},
			Scripts: eventScripts,
		},
		LogOutput:  logLevelFilter,
		RPCAddr:    config.RPCAddr,
		SerfConfig: serfConfig,
	}

	ui.Output("Starting Serf agent...")
	if err := agent.Start(); err != nil {
		ui.Error(err.Error())
		return 1
	}
	defer agent.Shutdown()

	bindAddr := (&net.TCPAddr{IP: net.ParseIP(bindIP), Port: bindPort}).String()
	ui.Output("Serf agent running!")
	ui.Info(fmt.Sprintf("Node name: '%s'", config.NodeName))
	ui.Info(fmt.Sprintf("Bind addr: '%s'", bindAddr))
	ui.Info(fmt.Sprintf(" RPC addr: '%s'", config.RPCAddr))
	ui.Info(fmt.Sprintf("Encrypted: %#v", config.EncryptKey != ""))

	if len(config.StartJoin) > 0 {
		ui.Output("Joining cluster...")
		n, err := agent.Join(config.StartJoin, true)
		if err != nil {
			ui.Error(err.Error())
			return 1
		}

		ui.Info(fmt.Sprintf("Join completed. Synced with %d initial agents", n))
	}

	ui.Info("")
	ui.Output("Log data will now stream in as it occurs:\n")
	logGate.Flush()

	graceful, forceful := c.startShutdownWatcher(agent, ui)
	select {
	case <-graceful:
	case <-forceful:
		// Forcefully shut down, return a bad exit status.
		return 1
	}

	return 0
}
Exemple #30
0
// 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
}