2015-08-26 21:27:44 +00:00
|
|
|
package fingerprint
|
|
|
|
|
|
|
|
import (
|
2015-08-27 14:19:53 +00:00
|
|
|
"fmt"
|
2015-08-26 21:27:44 +00:00
|
|
|
"log"
|
|
|
|
|
|
|
|
"github.com/hashicorp/nomad/client/config"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
|
|
"github.com/shirou/gopsutil/cpu"
|
|
|
|
)
|
|
|
|
|
|
|
|
// CPUFingerprint is used to fingerprint the CPU
|
|
|
|
type CPUFingerprint struct {
|
2015-11-05 21:46:02 +00:00
|
|
|
StaticFingerprinter
|
2015-08-26 21:27:44 +00:00
|
|
|
logger *log.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewCPUFingerprint is used to create a CPU fingerprint
|
|
|
|
func NewCPUFingerprint(logger *log.Logger) Fingerprint {
|
2015-08-27 00:16:34 +00:00
|
|
|
f := &CPUFingerprint{logger: logger}
|
2015-08-26 21:27:44 +00:00
|
|
|
return f
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *CPUFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
2016-05-09 15:19:04 +00:00
|
|
|
cpuInfo, err := cpu.Info()
|
2015-08-26 21:27:44 +00:00
|
|
|
if err != nil {
|
|
|
|
f.logger.Println("[WARN] Error reading CPU information:", err)
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2015-08-27 14:19:53 +00:00
|
|
|
var mhz float64
|
2015-08-26 21:27:44 +00:00
|
|
|
var modelName string
|
2015-08-27 14:19:53 +00:00
|
|
|
|
2016-06-17 02:41:01 +00:00
|
|
|
// Assume all CPUs found have same Model. Log if not. If cpu.Info()
|
|
|
|
// returns nil above, this loop is still safe. Don't assume all
|
|
|
|
// platforms return one entry in cpuInfo per core.
|
2015-08-27 14:19:53 +00:00
|
|
|
for _, c := range cpuInfo {
|
|
|
|
mhz += c.Mhz
|
|
|
|
|
2015-08-26 21:27:44 +00:00
|
|
|
if modelName != "" && modelName != c.ModelName {
|
|
|
|
f.logger.Println("[WARN] Found different model names in the same CPU information. Recording last found")
|
|
|
|
}
|
|
|
|
modelName = c.ModelName
|
|
|
|
}
|
2015-08-27 20:35:54 +00:00
|
|
|
// Get average CPU frequency
|
|
|
|
mhz /= float64(len(cpuInfo))
|
2015-08-27 14:19:53 +00:00
|
|
|
|
|
|
|
if mhz > 0 {
|
|
|
|
node.Attributes["cpu.frequency"] = fmt.Sprintf("%.6f", mhz)
|
2016-05-09 19:21:51 +00:00
|
|
|
f.logger.Printf("[DEBUG] fingerprint.cpu: frequency: %02.1fMHz", mhz)
|
2015-08-27 14:19:53 +00:00
|
|
|
}
|
|
|
|
|
2016-06-17 02:41:01 +00:00
|
|
|
var numCores int
|
|
|
|
if numCores, err = cpu.Counts(true); err != nil {
|
|
|
|
numCores = 1
|
|
|
|
f.logger.Println("[WARN] Unable to obtain the number of CPUs, defaulting to %d CPU", numCores)
|
2016-05-09 19:22:40 +00:00
|
|
|
}
|
|
|
|
|
2015-08-26 21:27:44 +00:00
|
|
|
if numCores > 0 {
|
2015-08-27 14:19:53 +00:00
|
|
|
node.Attributes["cpu.numcores"] = fmt.Sprintf("%d", numCores)
|
2016-05-09 19:21:51 +00:00
|
|
|
f.logger.Printf("[DEBUG] fingerprint.cpu: core count: %d", numCores)
|
2015-08-27 14:19:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if mhz > 0 && numCores > 0 {
|
2015-08-27 19:15:56 +00:00
|
|
|
tc := float64(numCores) * mhz
|
|
|
|
node.Attributes["cpu.totalcompute"] = fmt.Sprintf("%.6f", tc)
|
|
|
|
|
|
|
|
if node.Resources == nil {
|
|
|
|
node.Resources = &structs.Resources{}
|
|
|
|
}
|
|
|
|
|
2015-09-23 18:14:32 +00:00
|
|
|
node.Resources.CPU = int(tc)
|
2015-08-26 21:27:44 +00:00
|
|
|
}
|
2015-08-27 14:19:53 +00:00
|
|
|
|
2015-08-26 21:27:44 +00:00
|
|
|
if modelName != "" {
|
|
|
|
node.Attributes["cpu.modelname"] = modelName
|
|
|
|
}
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
}
|