package config import ( "fmt" "io" "strconv" "strings" "time" "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 // Network interface to be used in network fingerprinting NetworkInterface string // Network speed is the default speed of network interfaces if they can not // be determined dynamically. NetworkSpeed int // MaxKillTimeout allows capping the user-specifiable KillTimeout. If the // task's KillTimeout is greater than the MaxKillTimeout, MaxKillTimeout is // used. MaxKillTimeout time.Duration // 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 // ClientMaxPort is the upper range of the ports that the client uses for // communicating with plugin subsystems ClientMaxPort uint // ClientMinPort is the lower range of the ports that the client uses for // communicating with plugin subsystems ClientMinPort uint // Options provides arbitrary key-value configuration for nomad internals, // like fingerprinters and drivers. The format is: // // namespace.option = value Options map[string]string // Version is the version of the Nomad client Version string } func (c *Config) Copy() *Config { nc := new(Config) *nc = *c nc.Node = nc.Node.Copy() nc.Servers = structs.CopySliceString(nc.Servers) nc.Options = structs.CopyMapStringString(nc.Options) return nc } // Read returns the specified configuration value or "". func (c *Config) Read(id string) string { val, ok := c.Options[id] if !ok { return "" } return val } // ReadDefault returns the specified configuration value, or the specified // default value if none is set. func (c *Config) ReadDefault(id string, defaultValue string) string { val := c.Read(id) if val != "" { return val } return defaultValue } // ReadBool parses the specified option as a boolean. func (c *Config) ReadBool(id string) (bool, error) { val, ok := c.Options[id] if !ok { return false, fmt.Errorf("Specified config is missing from options") } bval, err := strconv.ParseBool(val) if err != nil { return false, fmt.Errorf("Failed to parse %s as bool: %s", val, err) } return bval, nil } // ReadBoolDefault tries to parse the specified option as a boolean. If there is // an error in parsing, the default option is returned. func (c *Config) ReadBoolDefault(id string, defaultValue bool) bool { val, err := c.ReadBool(id) if err != nil { return defaultValue } return val } // ReadStringListToMap tries to parse the specified option as a comma seperated list. // If there is an error in parsing, an empty list is returned. func (c *Config) ReadStringListToMap(key string) map[string]struct{} { s := strings.TrimSpace(c.Read(key)) list := make(map[string]struct{}) if s != "" { for _, e := range strings.Split(s, ",") { trimmed := strings.TrimSpace(e) list[trimmed] = struct{}{} } } return list }