Filling in Agent basics

This commit is contained in:
Armon Dadgar 2013-12-20 15:33:13 -08:00
parent d9a1fb02a1
commit 0e4b5720d9
3 changed files with 152 additions and 4 deletions

View file

@ -1,5 +1,10 @@
package agent package agent
import (
"fmt"
"github.com/hashicorp/consul/consul"
)
/* /*
The agent is the long running process that is run on every machine. The agent is the long running process that is run on every machine.
It exposes an RPC interface that is used by the CLI to control the It exposes an RPC interface that is used by the CLI to control the
@ -10,6 +15,11 @@ package agent
*/ */
type Agent struct { type Agent struct {
config *Config config *Config
// We have one of a client or a server, depending
// on our configuration
server *consul.Server
client *consul.Client
} }
// Create is used to create a new Agent. Returns // Create is used to create a new Agent. Returns
@ -18,16 +28,102 @@ func Create(config *Config) (*Agent, error) {
agent := &Agent{ agent := &Agent{
config: config, config: config,
} }
// Setup either the client or the server
var err error
if config.Server {
err = agent.setupServer()
} else {
err = agent.setupClient()
}
if err != nil {
return nil, err
}
return agent, nil return agent, nil
} }
// consulConfig is used to return a consul configuration
func (a *Agent) consulConfig() *consul.Config {
// Start with the provided config or default config
var base *consul.Config
if a.config.ConsulConfig != nil {
base = a.config.ConsulConfig
} else {
base = consul.DefaultConfig()
}
// Override with our config
if a.config.Datacenter != "" {
base.Datacenter = a.config.Datacenter
}
if a.config.DataDir != "" {
base.DataDir = a.config.DataDir
}
if a.config.NodeName != "" {
base.NodeName = a.config.NodeName
}
if a.config.SerfBindAddr != "" {
base.SerfLANConfig.MemberlistConfig.BindAddr = a.config.SerfBindAddr
base.SerfWANConfig.MemberlistConfig.BindAddr = a.config.SerfBindAddr
}
if a.config.SerfLanPort != 0 {
base.SerfLANConfig.MemberlistConfig.Port = a.config.SerfLanPort
}
if a.config.SerfWanPort != 0 {
base.SerfWANConfig.MemberlistConfig.Port = a.config.SerfWanPort
}
if a.config.ServerRPCAddr != "" {
base.RPCAddr = a.config.ServerRPCAddr
}
return base
}
// setupServer is used to initialize the Consul server
func (a *Agent) setupServer() error {
server, err := consul.NewServer(a.consulConfig())
if err != nil {
return fmt.Errorf("Failed to start Consul server: %v", err)
}
a.server = server
return nil
}
// setupClient is used to initialize the Consul client
func (a *Agent) setupClient() error {
client, err := consul.NewClient(a.consulConfig())
if err != nil {
return fmt.Errorf("Failed to start Consul client: %v", err)
}
a.client = client
return nil
}
// RPC is used to make an RPC call to the Consul servers
// This allows the agent to implement the Consul.Interface
func (a *Agent) RPC(method string, args interface{}, reply interface{}) error {
if a.server != nil {
return a.server.RPC(method, args, reply)
}
return a.client.RPC(method, args, reply)
}
// Leave prepares the agent for a graceful shutdown // Leave prepares the agent for a graceful shutdown
func (a *Agent) Leave() error { func (a *Agent) Leave() error {
return nil if a.server != nil {
return a.server.Leave()
} else {
return a.client.Leave()
}
} }
// Shutdown is used to hard stop the agent. Should be preceeded // Shutdown is used to hard stop the agent. Should be preceeded
// by a call to Leave to do it gracefully. // by a call to Leave to do it gracefully.
func (a *Agent) Shutdown() error { func (a *Agent) Shutdown() error {
return nil if a.server != nil {
return a.server.Shutdown()
} else {
return a.client.Shutdown()
}
} }

View file

@ -1,12 +1,62 @@
package agent package agent
import (
"github.com/hashicorp/consul/consul"
)
// This is the default port we use for co
const DefaultBindPort int = 8300
// Config is the configuration that can be set for an Agent. // Config is the configuration that can be set for an Agent.
// Some of this is configurable as CLI flags, but most must // Some of this is configurable as CLI flags, but most must
// be set using a configuration file. // be set using a configuration file.
type Config struct { type Config struct {
// Datacenter is the datacenter this node is in. Defaults to dc1
Datacenter string
// DataDir is the directory to store our state in
DataDir string
// LogLevel is the level of the logs to putout
LogLevel string
// Node name is the name we use to advertise. Defaults to hostname.
NodeName string
// RPCAddr is the address and port to listen on for the
// agent's RPC interface.
RPCAddr string
// BindAddr is the address that Consul's RPC and Serf's will
// bind to. This address should be routable by all other hosts.
SerfBindAddr string
// SerfLanPort is the port we use for the lan-local serf cluster
// This is used for all nodes.
SerfLanPort int
// SerfWanPort is the port we use for the wan serf cluster.
// This is only for the Consul servers
SerfWanPort int
// ServerRPCAddr is the address we use for Consul server communication.
// Defaults to 0.0.0.0:8300
ServerRPCAddr string
// Server controls if this agent acts like a Consul server,
// or merely as a client. Servers have more state, take part
// in leader election, etc.
Server bool
// ConsulConfig can either be provided or a default one created
ConsulConfig *consul.Config
} }
// DefaultConfig is used to return a sane default configuration // DefaultConfig is used to return a sane default configuration
func DefaultConfig() *Config { func DefaultConfig() *Config {
return &Config{} return &Config{
LogLevel: "INFO",
RPCAddr: "127.0.0.1:8400",
Server: false,
}
} }

View file

@ -9,7 +9,9 @@ import (
) )
const ( const (
DefaultDC = "dc1"
DefaultRPCAddr = "0.0.0.0:8300" DefaultRPCAddr = "0.0.0.0:8300"
DefaultRPCPort = 8000
DefaultLANSerfPort = 8301 DefaultLANSerfPort = 8301
DefaultWANSerfPort = 8302 DefaultWANSerfPort = 8302
) )
@ -51,7 +53,7 @@ func DefaultConfig() *Config {
} }
conf := &Config{ conf := &Config{
Datacenter: "dc1", Datacenter: DefaultDC,
NodeName: hostname, NodeName: hostname,
RPCAddr: DefaultRPCAddr, RPCAddr: DefaultRPCAddr,
RaftConfig: raft.DefaultConfig(), RaftConfig: raft.DefaultConfig(),