Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

F arm misc #2447

Merged
merged 2 commits into from
Mar 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions client/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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]
Expand Down
5 changes: 0 additions & 5 deletions client/driver/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,11 +612,6 @@ func (d *DockerDriver) dockerClients() (*docker.Client, *docker.Client, error) {
var err error
var merr multierror.Error
createClients.Do(func() {
if err = shelpers.Init(); err != nil {
d.logger.Printf("[FATAL] driver.docker: unable to initialize stats: %v", err)
return
}

// Default to using whatever is configured in docker.endpoint. If this is
// not specified we'll fall back on NewClientFromEnv which reads config from
// the DOCKER_* environment variables DOCKER_HOST, DOCKER_TLS_VERIFY, and
Expand Down
3 changes: 1 addition & 2 deletions client/driver/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
31 changes: 24 additions & 7 deletions client/fingerprint/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
node.Attributes["cpu.totalcompute"] = fmt.Sprintf("%.0f", tt)

setResources(int(tt))
return true, nil
}
3 changes: 3 additions & 0 deletions command/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions command/agent/config-test-fixtures/basic.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ client {
}
network_interface = "eth0"
network_speed = 100
cpu_compute = 4444
reserved {
cpu = 10
memory = 10
Expand Down
6 changes: 6 additions & 0 deletions command/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`

Expand Down Expand Up @@ -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
}
Expand Down
1 change: 1 addition & 0 deletions command/agent/config_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions command/agent/config_parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func TestConfig_Parse(t *testing.T) {
},
NetworkInterface: "eth0",
NetworkSpeed: 100,
CpuCompute: 4444,
MaxKillTimeout: "10s",
ClientMinPort: 1000,
ClientMaxPort: 2000,
Expand Down
2 changes: 2 additions & 0 deletions command/agent/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func TestConfig_Merge(t *testing.T) {
"foo": "bar",
},
NetworkSpeed: 100,
CpuCompute: 100,
MaxKillTimeout: "20s",
ClientMaxPort: 19996,
Reserved: &Resources{
Expand Down Expand Up @@ -202,6 +203,7 @@ func TestConfig_Merge(t *testing.T) {
ClientMaxPort: 20000,
ClientMinPort: 22000,
NetworkSpeed: 105,
CpuCompute: 105,
MaxKillTimeout: "50s",
Reserved: &Resources{
CPU: 15,
Expand Down
6 changes: 2 additions & 4 deletions helper/discover/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}

Expand Down
12 changes: 6 additions & 6 deletions helper/stats/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
Expand Down