diff --git a/client/client.go b/client/client.go index 199f1a9bd..4c17fde16 100644 --- a/client/client.go +++ b/client/client.go @@ -2,7 +2,6 @@ package client import ( "fmt" - "io" "log" "net" "os" @@ -10,6 +9,7 @@ import ( "sync" "time" + "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/client/driver" "github.com/hashicorp/nomad/client/fingerprint" "github.com/hashicorp/nomad/nomad" @@ -37,45 +37,9 @@ const ( devModeRetryIntv = time.Second ) -// RPCHandler can be provided to the Client if there is a local server -// to avoid going over the network. If not provided, the Client will -// maintain a connection pool to the servers -type RPCHandler interface { - RPC(method string, args interface{}, reply interface{}) error -} - -// Config is used to parameterize and configure the behavior of the client -type Config struct { - // DevMode controls if we are in a development mode which - // avoids persistent storage. - DevMode bool - - // StateDir is where we store our state - StateDir string - - // AllocDir is where we store data for allocations - AllocDir string - - // LogOutput is the destination for logs - LogOutput io.Writer - - // Region is the clients region - Region string - - // Servers is a list of known server addresses. These are as "host:port" - Servers []string - - // RPCHandler can be provided to avoid network traffic if the - // server is running locally. - RPCHandler RPCHandler - - // Node provides the base node - Node *structs.Node -} - // DefaultConfig returns the default configuration -func DefaultConfig() *Config { - return &Config{ +func DefaultConfig() *config.Config { + return &config.Config{ LogOutput: os.Stderr, Region: "region1", } @@ -85,7 +49,7 @@ func DefaultConfig() *Config { // are expected to register as a schedulable node to the servers, and to // run allocations as determined by the servers. type Client struct { - config *Config + config *config.Config logger *log.Logger @@ -108,14 +72,14 @@ type Client struct { } // NewClient is used to create a new client from the given configuration -func NewClient(config *Config) (*Client, error) { +func NewClient(cfg *config.Config) (*Client, error) { // Create a logger - logger := log.New(config.LogOutput, "", log.LstdFlags) + logger := log.New(cfg.LogOutput, "", log.LstdFlags) // Create the client c := &Client{ - config: config, - connPool: nomad.NewPool(config.LogOutput, clientRPCCache, clientMaxStreams, nil), + config: cfg, + connPool: nomad.NewPool(cfg.LogOutput, clientRPCCache, clientMaxStreams, nil), logger: logger, allocs: make(map[string]*AllocRunner), shutdownCh: make(chan struct{}), @@ -315,7 +279,7 @@ func (c *Client) fingerprint() error { if err != nil { return err } - applies, err := f.Fingerprint(c.config.Node) + applies, err := f.Fingerprint(c.config, c.config.Node) if err != nil { return err } @@ -335,7 +299,7 @@ func (c *Client) setupDrivers() error { if err != nil { return err } - applies, err := d.Fingerprint(c.config.Node) + applies, err := d.Fingerprint(c.config, c.config.Node) if err != nil { return err } diff --git a/client/client_test.go b/client/client_test.go index 5c2c57e8a..ffcf681f8 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" @@ -56,7 +57,7 @@ func testServer(t *testing.T, cb func(*nomad.Config)) (*nomad.Server, string) { return server, config.RPCAddr.String() } -func testClient(t *testing.T, cb func(c *Config)) *Client { +func testClient(t *testing.T, cb func(c *config.Config)) *Client { conf := DefaultConfig() if cb != nil { cb(conf) @@ -80,7 +81,7 @@ func TestClient_RPC(t *testing.T) { s1, addr := testServer(t, nil) defer s1.Shutdown() - c1 := testClient(t, func(c *Config) { + c1 := testClient(t, func(c *config.Config) { c.Servers = []string{addr} }) defer c1.Shutdown() @@ -99,7 +100,7 @@ func TestClient_RPC_Passthrough(t *testing.T) { s1, _ := testServer(t, nil) defer s1.Shutdown() - c1 := testClient(t, func(c *Config) { + c1 := testClient(t, func(c *config.Config) { c.RPCHandler = s1 }) defer c1.Shutdown() @@ -144,7 +145,7 @@ func TestClient_Register(t *testing.T) { defer s1.Shutdown() testutil.WaitForLeader(t, s1.RPC) - c1 := testClient(t, func(c *Config) { + c1 := testClient(t, func(c *config.Config) { c.RPCHandler = s1 }) defer c1.Shutdown() diff --git a/client/config/config.go b/client/config/config.go new file mode 100644 index 000000000..ec83d0718 --- /dev/null +++ b/client/config/config.go @@ -0,0 +1,43 @@ +package config + +import ( + "io" + + "github.com/hashicorp/nomad/nomad/structs" +) + +// RPCHandler can be provided to the Client if there is a local server +// to avoid going over the network. If not provided, the Client will +// maintain a connection pool to the servers +type RPCHandler interface { + RPC(method string, args interface{}, reply interface{}) error +} + +// Config is used to parameterize and configure the behavior of the client +type Config struct { + // DevMode controls if we are in a development mode which + // avoids persistent storage. + DevMode bool + + // StateDir is where we store our state + StateDir string + + // AllocDir is where we store data for allocations + AllocDir string + + // LogOutput is the destination for logs + LogOutput io.Writer + + // Region is the clients region + Region string + + // Servers is a list of known server addresses. These are as "host:port" + Servers []string + + // RPCHandler can be provided to avoid network traffic if the + // server is running locally. + RPCHandler RPCHandler + + // Node provides the base node + Node *structs.Node +} diff --git a/client/driver/exec.go b/client/driver/exec.go index 553423903..dc98b088c 100644 --- a/client/driver/exec.go +++ b/client/driver/exec.go @@ -3,6 +3,7 @@ package driver import ( "log" + "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad/structs" ) @@ -26,7 +27,7 @@ func NewExecDriver(logger *log.Logger) Driver { return d } -func (d *ExecDriver) Fingerprint(node *structs.Node) (bool, error) { +func (d *ExecDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) { // We can always do a fork/exec node.Attributes["driver.exec"] = "1" return true, nil diff --git a/client/driver/exec_test.go b/client/driver/exec_test.go index d6b7adb5f..88cc21e20 100644 --- a/client/driver/exec_test.go +++ b/client/driver/exec_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad/structs" ) @@ -17,7 +18,7 @@ func TestExecDriver_Fingerprint(t *testing.T) { node := &structs.Node{ Attributes: make(map[string]string), } - apply, err := d.Fingerprint(node) + apply, err := d.Fingerprint(&config.Config{}, node) if err != nil { t.Fatalf("err: %v", err) } diff --git a/client/fingerprint/arch.go b/client/fingerprint/arch.go index 4e65bb0c8..b49147eb0 100644 --- a/client/fingerprint/arch.go +++ b/client/fingerprint/arch.go @@ -4,6 +4,7 @@ import ( "log" "runtime" + client "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad/structs" ) @@ -18,7 +19,7 @@ func NewArchFingerprint(logger *log.Logger) Fingerprint { return f } -func (f *ArchFingerprint) Fingerprint(node *structs.Node) (bool, error) { +func (f *ArchFingerprint) Fingerprint(config *client.Config, node *structs.Node) (bool, error) { node.Attributes["arch"] = runtime.GOARCH f.logger.Printf("[DEBUG] fingerprint.arch: detected '%s'", runtime.GOARCH) return true, nil diff --git a/client/fingerprint/arch_test.go b/client/fingerprint/arch_test.go index a27cc719e..f92f90121 100644 --- a/client/fingerprint/arch_test.go +++ b/client/fingerprint/arch_test.go @@ -3,6 +3,7 @@ package fingerprint import ( "testing" + "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad/structs" ) @@ -11,7 +12,7 @@ func TestArchFingerprint(t *testing.T) { node := &structs.Node{ Attributes: make(map[string]string), } - ok, err := f.Fingerprint(node) + ok, err := f.Fingerprint(&config.Config{}, node) if err != nil { t.Fatalf("err: %v", err) } diff --git a/client/fingerprint/fingerprint.go b/client/fingerprint/fingerprint.go index 161e1aaee..cfdbe5891 100644 --- a/client/fingerprint/fingerprint.go +++ b/client/fingerprint/fingerprint.go @@ -4,6 +4,7 @@ import ( "fmt" "log" + "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad/structs" ) @@ -38,5 +39,5 @@ type Factory func(*log.Logger) Fingerprint type Fingerprint interface { // Fingerprint is used to update properties of the Node, // and returns if the fingerprint was applicable and a potential error. - Fingerprint(*structs.Node) (bool, error) + Fingerprint(*config.Config, *structs.Node) (bool, error) } diff --git a/client/fingerprint/os.go b/client/fingerprint/os.go index 6983270de..9191fa9fe 100644 --- a/client/fingerprint/os.go +++ b/client/fingerprint/os.go @@ -4,6 +4,7 @@ import ( "log" "runtime" + "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad/structs" ) @@ -18,7 +19,7 @@ func NewOSFingerprint(logger *log.Logger) Fingerprint { return f } -func (f *OSFingerprint) Fingerprint(node *structs.Node) (bool, error) { +func (f *OSFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) { node.Attributes["os"] = runtime.GOOS f.logger.Printf("[DEBUG] fingerprint.os: detected '%s'", runtime.GOOS) return true, nil diff --git a/client/fingerprint/os_test.go b/client/fingerprint/os_test.go index 3e3384cf2..1b6962cd8 100644 --- a/client/fingerprint/os_test.go +++ b/client/fingerprint/os_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad/structs" ) @@ -17,7 +18,7 @@ func TestOSFingerprint(t *testing.T) { node := &structs.Node{ Attributes: make(map[string]string), } - ok, err := f.Fingerprint(node) + ok, err := f.Fingerprint(&config.Config{}, node) if err != nil { t.Fatalf("err: %v", err) }