Various fixes
This PR: * Uses Go 1.8 executable lookup * Stores any err message from stats init method * Allows overriding of Cpu Compute for hosts where it can't be detected
This commit is contained in:
parent
55f9d1ee84
commit
a1a7941dec
|
@ -87,6 +87,10 @@ type Config struct {
|
|||
// be determined dynamically.
|
||||
NetworkSpeed int
|
||||
|
||||
// CpuCompute is the default total CPU compute if they can not be determined
|
||||
// dynamically. It should be given as Cores * MHz (2 Cores * 2 Ghz = 4000)
|
||||
CpuCompute int
|
||||
|
||||
// MaxKillTimeout allows capping the user-specifiable KillTimeout. If the
|
||||
// task's KillTimeout is greater than the MaxKillTimeout, MaxKillTimeout is
|
||||
// used.
|
||||
|
@ -242,6 +246,29 @@ func (c *Config) ReadBoolDefault(id string, defaultValue bool) bool {
|
|||
return val
|
||||
}
|
||||
|
||||
// ReadInt parses the specified option as a int.
|
||||
func (c *Config) ReadInt(id string) (int, error) {
|
||||
val, ok := c.Options[id]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("Specified config is missing from options")
|
||||
}
|
||||
ival, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("Failed to parse %s as int: %s", val, err)
|
||||
}
|
||||
return ival, nil
|
||||
}
|
||||
|
||||
// ReadIntDefault tries to parse the specified option as a int. If there is
|
||||
// an error in parsing, the default option is returned.
|
||||
func (c *Config) ReadIntDefault(id string, defaultValue int) int {
|
||||
val, err := c.ReadInt(id)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// ReadDuration parses the specified option as a duration.
|
||||
func (c *Config) ReadDuration(id string) (time.Duration, error) {
|
||||
val, ok := c.Options[id]
|
||||
|
|
|
@ -207,8 +207,7 @@ type UniversalExecutor struct {
|
|||
// NewExecutor returns an Executor
|
||||
func NewExecutor(logger *log.Logger) Executor {
|
||||
if err := shelpers.Init(); err != nil {
|
||||
logger.Printf("[FATAL] executor: unable to initialize stats: %v", err)
|
||||
return nil
|
||||
logger.Printf("[ERR] executor: unable to initialize stats: %v", err)
|
||||
}
|
||||
|
||||
exec := &UniversalExecutor{
|
||||
|
|
|
@ -22,8 +22,29 @@ func NewCPUFingerprint(logger *log.Logger) Fingerprint {
|
|||
}
|
||||
|
||||
func (f *CPUFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
||||
setResources := func(totalCompute int) {
|
||||
if node.Resources == nil {
|
||||
node.Resources = &structs.Resources{}
|
||||
}
|
||||
|
||||
node.Resources.CPU = totalCompute
|
||||
}
|
||||
|
||||
if err := stats.Init(); err != nil {
|
||||
return false, fmt.Errorf("Unable to obtain CPU information: %v", err)
|
||||
err := fmt.Errorf("Unable to obtain CPU information: %v", err)
|
||||
|
||||
if cfg.CpuCompute != 0 {
|
||||
f.logger.Printf("[DEBUG] fingerprint.cpu: %v. Using specified cpu compute %d", err, cfg.CpuCompute)
|
||||
setResources(cfg.CpuCompute)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
f.logger.Printf("[ERR] fingerprint.cpu: %v", err)
|
||||
f.logger.Printf("[INFO] fingerprint.cpu: cpu compute may be set manually"+
|
||||
" using the client config option %q on machines where cpu information"+
|
||||
" can not be automatically detected.", "cpu_compute")
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
modelName := stats.CPUModelName()
|
||||
|
@ -40,13 +61,9 @@ func (f *CPUFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (bo
|
|||
f.logger.Printf("[DEBUG] fingerprint.cpu: core count: %d", numCores)
|
||||
|
||||
tt := stats.TotalTicksAvailable()
|
||||
|
||||
node.Attributes["cpu.totalcompute"] = fmt.Sprintf("%.0f", tt)
|
||||
|
||||
if node.Resources == nil {
|
||||
node.Resources = &structs.Resources{}
|
||||
}
|
||||
|
||||
node.Resources.CPU = int(tt)
|
||||
|
||||
setResources(int(tt))
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -259,6 +259,9 @@ func (a *Agent) clientConfig() (*clientconfig.Config, error) {
|
|||
if a.config.Client.NetworkSpeed != 0 {
|
||||
conf.NetworkSpeed = a.config.Client.NetworkSpeed
|
||||
}
|
||||
if a.config.Client.CpuCompute != 0 {
|
||||
conf.CpuCompute = a.config.Client.CpuCompute
|
||||
}
|
||||
if a.config.Client.MaxKillTimeout != "" {
|
||||
dur, err := time.ParseDuration(a.config.Client.MaxKillTimeout)
|
||||
if err != nil {
|
||||
|
|
|
@ -39,6 +39,7 @@ client {
|
|||
}
|
||||
network_interface = "eth0"
|
||||
network_speed = 100
|
||||
cpu_compute = 4444
|
||||
reserved {
|
||||
cpu = 10
|
||||
memory = 10
|
||||
|
|
|
@ -182,6 +182,9 @@ type ClientConfig struct {
|
|||
// speed.
|
||||
NetworkSpeed int `mapstructure:"network_speed"`
|
||||
|
||||
// CpuCompute is used to override any detected or default total CPU compute.
|
||||
CpuCompute int `mapstructure:"cpu_compute"`
|
||||
|
||||
// MaxKillTimeout allows capping the user-specifiable KillTimeout.
|
||||
MaxKillTimeout string `mapstructure:"max_kill_timeout"`
|
||||
|
||||
|
@ -916,6 +919,9 @@ func (a *ClientConfig) Merge(b *ClientConfig) *ClientConfig {
|
|||
if b.NetworkSpeed != 0 {
|
||||
result.NetworkSpeed = b.NetworkSpeed
|
||||
}
|
||||
if b.CpuCompute != 0 {
|
||||
result.CpuCompute = b.CpuCompute
|
||||
}
|
||||
if b.MaxKillTimeout != "" {
|
||||
result.MaxKillTimeout = b.MaxKillTimeout
|
||||
}
|
||||
|
|
|
@ -336,6 +336,7 @@ func parseClient(result **ClientConfig, list *ast.ObjectList) error {
|
|||
"chroot_env",
|
||||
"network_interface",
|
||||
"network_speed",
|
||||
"cpu_compute",
|
||||
"max_kill_timeout",
|
||||
"client_max_port",
|
||||
"client_min_port",
|
||||
|
|
|
@ -59,6 +59,7 @@ func TestConfig_Parse(t *testing.T) {
|
|||
},
|
||||
NetworkInterface: "eth0",
|
||||
NetworkSpeed: 100,
|
||||
CpuCompute: 4444,
|
||||
MaxKillTimeout: "10s",
|
||||
ClientMinPort: 1000,
|
||||
ClientMaxPort: 2000,
|
||||
|
|
|
@ -76,6 +76,7 @@ func TestConfig_Merge(t *testing.T) {
|
|||
"foo": "bar",
|
||||
},
|
||||
NetworkSpeed: 100,
|
||||
CpuCompute: 100,
|
||||
MaxKillTimeout: "20s",
|
||||
ClientMaxPort: 19996,
|
||||
Reserved: &Resources{
|
||||
|
@ -202,6 +203,7 @@ func TestConfig_Merge(t *testing.T) {
|
|||
ClientMaxPort: 20000,
|
||||
ClientMinPort: 22000,
|
||||
NetworkSpeed: 105,
|
||||
CpuCompute: 105,
|
||||
MaxKillTimeout: "50s",
|
||||
Reserved: &Resources{
|
||||
CPU: 15,
|
||||
|
|
|
@ -6,8 +6,6 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/kardianos/osext"
|
||||
)
|
||||
|
||||
// Checks the current executable, then $GOPATH/bin, and finally the CWD, in that
|
||||
|
@ -19,12 +17,12 @@ func NomadExecutable() (string, error) {
|
|||
}
|
||||
|
||||
// Check the current executable.
|
||||
bin, err := osext.Executable()
|
||||
bin, err := os.Executable()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to determine the nomad executable: %v", err)
|
||||
}
|
||||
|
||||
if filepath.Base(bin) == nomadExe {
|
||||
if _, err := os.Stat(bin); err == nil {
|
||||
return bin, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -14,20 +14,20 @@ var (
|
|||
cpuNumCores int
|
||||
cpuTotalTicks float64
|
||||
|
||||
initErr error
|
||||
onceLer sync.Once
|
||||
)
|
||||
|
||||
func Init() error {
|
||||
var err error
|
||||
onceLer.Do(func() {
|
||||
if cpuNumCores, err = cpu.Counts(true); err != nil {
|
||||
err = fmt.Errorf("Unable to determine the number of CPU cores available: %v", err)
|
||||
if cpuNumCores, initErr = cpu.Counts(true); initErr != nil {
|
||||
initErr = fmt.Errorf("Unable to determine the number of CPU cores available: %v", initErr)
|
||||
return
|
||||
}
|
||||
|
||||
var cpuInfo []cpu.InfoStat
|
||||
if cpuInfo, err = cpu.Info(); err != nil {
|
||||
err = fmt.Errorf("Unable to obtain CPU information: %v", err)
|
||||
if cpuInfo, initErr = cpu.Info(); initErr != nil {
|
||||
initErr = fmt.Errorf("Unable to obtain CPU information: %v", initErr)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ func Init() error {
|
|||
cpuMhzPerCore = math.Floor(cpuMhzPerCore)
|
||||
cpuTotalTicks = math.Floor(float64(cpuNumCores) * cpuMhzPerCore)
|
||||
})
|
||||
return err
|
||||
return initErr
|
||||
}
|
||||
|
||||
// CPUModelName returns the number of CPU cores available
|
||||
|
|
Loading…
Reference in New Issue