commit
feda8114cb
|
@ -175,14 +175,159 @@ func DefaultConfig() *Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge merges two configurations.
|
// Merge merges two configurations.
|
||||||
func (c *Config) Merge(c2 *Config) *Config {
|
func (a *Config) Merge(b *Config) *Config {
|
||||||
result := new(Config)
|
var result Config = *a
|
||||||
|
|
||||||
result.Telemetry = c.Telemetry
|
if b.Region != "" {
|
||||||
if c2.Telemetry != nil {
|
result.Region = b.Region
|
||||||
result.Telemetry = c2.Telemetry
|
|
||||||
}
|
}
|
||||||
return result
|
if b.Datacenter != "" {
|
||||||
|
result.Datacenter = b.Datacenter
|
||||||
|
}
|
||||||
|
if b.NodeName != "" {
|
||||||
|
result.NodeName = b.NodeName
|
||||||
|
}
|
||||||
|
if b.DataDir != "" {
|
||||||
|
result.DataDir = b.DataDir
|
||||||
|
}
|
||||||
|
if b.LogLevel != "" {
|
||||||
|
result.LogLevel = b.LogLevel
|
||||||
|
}
|
||||||
|
if b.HttpAddr != "" {
|
||||||
|
result.HttpAddr = b.HttpAddr
|
||||||
|
}
|
||||||
|
if b.EnableDebug {
|
||||||
|
result.EnableDebug = true
|
||||||
|
}
|
||||||
|
if b.LeaveOnInt {
|
||||||
|
result.LeaveOnInt = true
|
||||||
|
}
|
||||||
|
if b.LeaveOnTerm {
|
||||||
|
result.LeaveOnTerm = true
|
||||||
|
}
|
||||||
|
if b.EnableSyslog {
|
||||||
|
result.EnableSyslog = true
|
||||||
|
}
|
||||||
|
if b.SyslogFacility != "" {
|
||||||
|
result.SyslogFacility = b.SyslogFacility
|
||||||
|
}
|
||||||
|
if b.DisableUpdateCheck {
|
||||||
|
result.DisableUpdateCheck = true
|
||||||
|
}
|
||||||
|
if b.DisableAnonymousSignature {
|
||||||
|
result.DisableAnonymousSignature = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the telemetry config
|
||||||
|
if result.Telemetry == nil && b.Telemetry != nil {
|
||||||
|
telemetry := *b.Telemetry
|
||||||
|
result.Telemetry = &telemetry
|
||||||
|
} else if b.Telemetry != nil {
|
||||||
|
result.Telemetry = result.Telemetry.Merge(b.Telemetry)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the client config
|
||||||
|
if result.Client == nil && b.Client != nil {
|
||||||
|
client := *b.Client
|
||||||
|
result.Client = &client
|
||||||
|
} else if b.Client != nil {
|
||||||
|
result.Client = result.Client.Merge(b.Client)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the server config
|
||||||
|
if result.Server == nil && b.Server != nil {
|
||||||
|
server := *b.Server
|
||||||
|
result.Server = &server
|
||||||
|
} else if b.Server != nil {
|
||||||
|
result.Server = result.Server.Merge(b.Server)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge is used to merge two server configs together
|
||||||
|
func (a *ServerConfig) Merge(b *ServerConfig) *ServerConfig {
|
||||||
|
var result ServerConfig = *a
|
||||||
|
|
||||||
|
if b.Enabled {
|
||||||
|
result.Enabled = true
|
||||||
|
}
|
||||||
|
if b.Bootstrap {
|
||||||
|
result.Bootstrap = true
|
||||||
|
}
|
||||||
|
if b.BootstrapExpect > 0 {
|
||||||
|
result.BootstrapExpect = b.BootstrapExpect
|
||||||
|
}
|
||||||
|
if b.DataDir != "" {
|
||||||
|
result.DataDir = b.DataDir
|
||||||
|
}
|
||||||
|
if b.ProtocolVersion != 0 {
|
||||||
|
result.ProtocolVersion = b.ProtocolVersion
|
||||||
|
}
|
||||||
|
if b.AdvertiseAddr != "" {
|
||||||
|
result.AdvertiseAddr = b.AdvertiseAddr
|
||||||
|
}
|
||||||
|
if b.BindAddr != "" {
|
||||||
|
result.BindAddr = b.BindAddr
|
||||||
|
}
|
||||||
|
if b.NumSchedulers != 0 {
|
||||||
|
result.NumSchedulers = b.NumSchedulers
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the schedulers
|
||||||
|
result.EnabledSchedulers = append(result.EnabledSchedulers, b.EnabledSchedulers...)
|
||||||
|
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge is used to merge two client configs together
|
||||||
|
func (a *ClientConfig) Merge(b *ClientConfig) *ClientConfig {
|
||||||
|
var result ClientConfig = *a
|
||||||
|
|
||||||
|
if b.Enabled {
|
||||||
|
result.Enabled = true
|
||||||
|
}
|
||||||
|
if b.StateDir != "" {
|
||||||
|
result.StateDir = b.StateDir
|
||||||
|
}
|
||||||
|
if b.AllocDir != "" {
|
||||||
|
result.AllocDir = b.AllocDir
|
||||||
|
}
|
||||||
|
if b.NodeID != "" {
|
||||||
|
result.NodeID = b.NodeID
|
||||||
|
}
|
||||||
|
if b.NodeClass != "" {
|
||||||
|
result.NodeClass = b.NodeClass
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the servers
|
||||||
|
result.Servers = append(result.Servers, b.Servers...)
|
||||||
|
|
||||||
|
// Add the meta map values
|
||||||
|
if result.Meta == nil {
|
||||||
|
result.Meta = make(map[string]string)
|
||||||
|
}
|
||||||
|
for k, v := range b.Meta {
|
||||||
|
result.Meta[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge is used to merge two telemetry configs together
|
||||||
|
func (a *Telemetry) Merge(b *Telemetry) *Telemetry {
|
||||||
|
var result Telemetry = *a
|
||||||
|
|
||||||
|
if b.StatsiteAddr != "" {
|
||||||
|
result.StatsiteAddr = b.StatsiteAddr
|
||||||
|
}
|
||||||
|
if b.StatsdAddr != "" {
|
||||||
|
result.StatsdAddr = b.StatsdAddr
|
||||||
|
}
|
||||||
|
if b.DisableHostname {
|
||||||
|
result.DisableHostname = true
|
||||||
|
}
|
||||||
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfig loads the configuration at the given path, regardless if
|
// LoadConfig loads the configuration at the given path, regardless if
|
||||||
|
|
|
@ -0,0 +1,233 @@
|
||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConfig_Merge(t *testing.T) {
|
||||||
|
c1 := &Config{
|
||||||
|
Region: "region1",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
NodeName: "node1",
|
||||||
|
DataDir: "/tmp/dir1",
|
||||||
|
LogLevel: "INFO",
|
||||||
|
HttpAddr: "127.0.0.1:4646",
|
||||||
|
EnableDebug: false,
|
||||||
|
LeaveOnInt: false,
|
||||||
|
LeaveOnTerm: false,
|
||||||
|
EnableSyslog: false,
|
||||||
|
SyslogFacility: "local0.info",
|
||||||
|
DisableUpdateCheck: false,
|
||||||
|
DisableAnonymousSignature: false,
|
||||||
|
Telemetry: &Telemetry{
|
||||||
|
StatsiteAddr: "127.0.0.1:8125",
|
||||||
|
StatsdAddr: "127.0.0.1:8125",
|
||||||
|
DisableHostname: false,
|
||||||
|
},
|
||||||
|
Client: &ClientConfig{
|
||||||
|
Enabled: false,
|
||||||
|
StateDir: "/tmp/state1",
|
||||||
|
AllocDir: "/tmp/alloc1",
|
||||||
|
NodeID: "node1",
|
||||||
|
NodeClass: "class1",
|
||||||
|
},
|
||||||
|
Server: &ServerConfig{
|
||||||
|
Enabled: false,
|
||||||
|
Bootstrap: false,
|
||||||
|
BootstrapExpect: 1,
|
||||||
|
DataDir: "/tmp/data1",
|
||||||
|
ProtocolVersion: 1,
|
||||||
|
AdvertiseAddr: "127.0.0.1:4647",
|
||||||
|
BindAddr: "127.0.0.1",
|
||||||
|
NumSchedulers: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
c2 := &Config{
|
||||||
|
Region: "region2",
|
||||||
|
Datacenter: "dc2",
|
||||||
|
NodeName: "node2",
|
||||||
|
DataDir: "/tmp/dir2",
|
||||||
|
LogLevel: "DEBUG",
|
||||||
|
HttpAddr: "0.0.0.0:80",
|
||||||
|
EnableDebug: true,
|
||||||
|
LeaveOnInt: true,
|
||||||
|
LeaveOnTerm: true,
|
||||||
|
EnableSyslog: true,
|
||||||
|
SyslogFacility: "local0.debug",
|
||||||
|
DisableUpdateCheck: true,
|
||||||
|
DisableAnonymousSignature: true,
|
||||||
|
Telemetry: &Telemetry{
|
||||||
|
StatsiteAddr: "127.0.0.2:8125",
|
||||||
|
StatsdAddr: "127.0.0.2:8125",
|
||||||
|
DisableHostname: true,
|
||||||
|
},
|
||||||
|
Client: &ClientConfig{
|
||||||
|
Enabled: true,
|
||||||
|
StateDir: "/tmp/state2",
|
||||||
|
AllocDir: "/tmp/alloc2",
|
||||||
|
NodeID: "node2",
|
||||||
|
NodeClass: "class2",
|
||||||
|
Servers: []string{"server2"},
|
||||||
|
Meta: map[string]string{"baz": "zip"},
|
||||||
|
},
|
||||||
|
Server: &ServerConfig{
|
||||||
|
Enabled: true,
|
||||||
|
Bootstrap: true,
|
||||||
|
BootstrapExpect: 2,
|
||||||
|
DataDir: "/tmp/data2",
|
||||||
|
ProtocolVersion: 2,
|
||||||
|
AdvertiseAddr: "127.0.0.2:4647",
|
||||||
|
BindAddr: "127.0.0.2",
|
||||||
|
NumSchedulers: 2,
|
||||||
|
EnabledSchedulers: []string{structs.JobTypeBatch},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
result := c1.Merge(c2)
|
||||||
|
if !reflect.DeepEqual(result, c2) {
|
||||||
|
t.Fatalf("bad:\n%#v\n%#v", result.Server, c2.Server)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfig_LoadConfigFile(t *testing.T) {
|
||||||
|
// Fails if the file doesn't exist
|
||||||
|
if _, err := LoadConfigFile("/unicorns/leprechauns"); err == nil {
|
||||||
|
t.Fatalf("expected error, got nothing")
|
||||||
|
}
|
||||||
|
|
||||||
|
fh, err := ioutil.TempFile("", "nomad")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(fh.Name())
|
||||||
|
|
||||||
|
// Invalid content returns error
|
||||||
|
if _, err := fh.WriteString("nope"); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if _, err := LoadConfigFile(fh.Name()); err == nil {
|
||||||
|
t.Fatalf("expected load error, got nothing")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid content parses successfully
|
||||||
|
if err := fh.Truncate(0); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if _, err := fh.Seek(0, 0); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if _, err := fh.WriteString(`{"region":"west"}`); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := LoadConfigFile(fh.Name())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if config.Region != "west" {
|
||||||
|
t.Fatalf("bad region: %q", config.Region)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfig_LoadConfigDir(t *testing.T) {
|
||||||
|
// Fails if the dir doesn't exist.
|
||||||
|
if _, err := LoadConfigDir("/unicorns/leprechauns"); err == nil {
|
||||||
|
t.Fatalf("expected error, got nothing")
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := ioutil.TempDir("", "nomad")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
file1 := filepath.Join(dir, "conf1.hcl")
|
||||||
|
err = ioutil.WriteFile(file1, []byte(`{"region":"west"}`), 0600)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file2 := filepath.Join(dir, "conf2.hcl")
|
||||||
|
err = ioutil.WriteFile(file2, []byte(`{"datacenter":"sfo"}`), 0600)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file3 := filepath.Join(dir, "conf3.hcl")
|
||||||
|
err = ioutil.WriteFile(file3, []byte(`nope`), 0600)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fails if we have a bad config file
|
||||||
|
if _, err := LoadConfigDir(dir); err == nil {
|
||||||
|
t.Fatalf("expected load error, got nothing")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Remove(file3); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Works if configs are valid
|
||||||
|
config, err := LoadConfigDir(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if config.Region != "west" || config.Datacenter != "sfo" {
|
||||||
|
t.Fatalf("bad: %#v", config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfig_LoadConfig(t *testing.T) {
|
||||||
|
// Fails if the target doesn't exist
|
||||||
|
if _, err := LoadConfig("/unicorns/leprechauns"); err == nil {
|
||||||
|
t.Fatalf("expected error, got nothing")
|
||||||
|
}
|
||||||
|
|
||||||
|
fh, err := ioutil.TempFile("", "nomad")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(fh.Name())
|
||||||
|
|
||||||
|
if _, err := fh.WriteString(`{"region":"west"}`); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Works on a config file
|
||||||
|
config, err := LoadConfig(fh.Name())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if config.Region != "west" {
|
||||||
|
t.Fatalf("bad: %#v", config)
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := ioutil.TempDir("", "nomad")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
file1 := filepath.Join(dir, "config1.hcl")
|
||||||
|
err = ioutil.WriteFile(file1, []byte(`{"datacenter":"sfo"}`), 0600)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Works on config dir
|
||||||
|
config, err = LoadConfig(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if config.Datacenter != "sfo" {
|
||||||
|
t.Fatalf("bad: %#v", config)
|
||||||
|
}
|
||||||
|
}
|
|
@ -111,8 +111,7 @@ func NewTestServer(t *testing.T, cb ServerConfigCallback) *TestServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
// TODO: Use "-config", configFile.Name()
|
cmd := exec.Command("nomad", "agent", "-dev", "-config", configFile.Name())
|
||||||
cmd := exec.Command("nomad", "agent", "-dev")
|
|
||||||
cmd.Stdout = stdout
|
cmd.Stdout = stdout
|
||||||
cmd.Stderr = stderr
|
cmd.Stderr = stderr
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
|
@ -127,7 +126,7 @@ func NewTestServer(t *testing.T, cb ServerConfigCallback) *TestServer {
|
||||||
PID: cmd.Process.Pid,
|
PID: cmd.Process.Pid,
|
||||||
t: t,
|
t: t,
|
||||||
|
|
||||||
HTTPAddr: "127.0.0.1:4646", // TODO nomadConfig.HTTPAddr,
|
HTTPAddr: nomadConfig.HTTPAddr,
|
||||||
HttpClient: client,
|
HttpClient: client,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue