diff --git a/.changelog/25108.txt b/.changelog/25108.txt new file mode 100644 index 000000000..e20059d0c --- /dev/null +++ b/.changelog/25108.txt @@ -0,0 +1,3 @@ +```release-note:improvement +cpustats: Add config "cpu_disable_dmidecode" to disable cpu detection using dmidecode +``` diff --git a/client/config/config.go b/client/config/config.go index 700d8feb8..3de44fe3d 100644 --- a/client/config/config.go +++ b/client/config/config.go @@ -123,6 +123,9 @@ type Config struct { // be determined dynamically. NetworkSpeed int + // CpuDisableDmidecode disables cpu fingerprinting using dmidecode on Linux + CpuDisableDmidecode bool + // 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 diff --git a/client/driver_manager_test.go b/client/driver_manager_test.go index 1a9eb1aeb..7278c5f36 100644 --- a/client/driver_manager_test.go +++ b/client/driver_manager_test.go @@ -19,7 +19,7 @@ import ( ) var ( - topology = numalib.Scan(numalib.PlatformScanners()) + topology = numalib.Scan(numalib.PlatformScanners(false)) ) // TestDriverManager_Fingerprint_Run asserts that node is populated with diff --git a/client/fingerprint/cpu.go b/client/fingerprint/cpu.go index afdcf687a..9cf310b5c 100644 --- a/client/fingerprint/cpu.go +++ b/client/fingerprint/cpu.go @@ -88,7 +88,7 @@ func (f *CPUFingerprint) initialize(request *FingerprintRequest) { } f.top = numalib.Scan(append( - numalib.PlatformScanners(), + numalib.PlatformScanners(request.Config.CpuDisableDmidecode), &numalib.ConfigScanner{ ReservableCores: reservableCores, ReservedCores: reservedCores, diff --git a/client/lib/numalib/detect_darwin.go b/client/lib/numalib/detect_darwin.go index 10f72640d..13a93b0dd 100644 --- a/client/lib/numalib/detect_darwin.go +++ b/client/lib/numalib/detect_darwin.go @@ -13,7 +13,7 @@ import ( ) // PlatformScanners returns the set of SystemScanner for macOS. -func PlatformScanners() []SystemScanner { +func PlatformScanners(_ bool) []SystemScanner { return []SystemScanner{ new(MacOS), } diff --git a/client/lib/numalib/detect_default.go b/client/lib/numalib/detect_default.go index 3f2f7b400..b62bb054b 100644 --- a/client/lib/numalib/detect_default.go +++ b/client/lib/numalib/detect_default.go @@ -7,7 +7,7 @@ package numalib // PlatformScanners returns the set of SystemScanner for systems without a // specific implementation. -func PlatformScanners() []SystemScanner { +func PlatformScanners(_ bool) []SystemScanner { return []SystemScanner{ new(Generic), } diff --git a/client/lib/numalib/detect_linux.go b/client/lib/numalib/detect_linux.go index aacb0bc6c..dafdd9c35 100644 --- a/client/lib/numalib/detect_linux.go +++ b/client/lib/numalib/detect_linux.go @@ -19,14 +19,16 @@ import ( ) // PlatformScanners returns the set of SystemScanner for Linux. -func PlatformScanners() []SystemScanner { - return []SystemScanner{ - new(Sysfs), - new(Smbios), - new(Cgroups1), - new(Cgroups2), - new(Fallback), +func PlatformScanners(cpuDisableDmidecode bool) []SystemScanner { + scanners := []SystemScanner{new(Sysfs)} + if !cpuDisableDmidecode { + scanners = append(scanners, new(Smbios)) } + scanners = append(scanners, new(Cgroups1)) + scanners = append(scanners, new(Cgroups2)) + scanners = append(scanners, new(Fallback)) + + return scanners } const ( diff --git a/client/lib/numalib/detect_noimpl_test.go b/client/lib/numalib/detect_noimpl_test.go index f7a20502c..6659f4288 100644 --- a/client/lib/numalib/detect_noimpl_test.go +++ b/client/lib/numalib/detect_noimpl_test.go @@ -17,7 +17,7 @@ func Test_NoImpl_yes(t *testing.T) { } func Test_NoImpl_no(t *testing.T) { - original := Scan(PlatformScanners()) + original := Scan(PlatformScanners(false)) fallback := NoImpl(original) must.EqOp(t, original, fallback) // pointer is same } diff --git a/client/lib/numalib/detect_test.go b/client/lib/numalib/detect_test.go index e3da7a93c..01558bfee 100644 --- a/client/lib/numalib/detect_test.go +++ b/client/lib/numalib/detect_test.go @@ -12,7 +12,7 @@ import ( // TestScanTopology is going to be different on every machine; even the CI // systems change sometimes so it's hard to make good assertions here. func TestScanTopology(t *testing.T) { - top := Scan(PlatformScanners()) + top := Scan(PlatformScanners(false)) must.Positive(t, top.UsableCompute()) must.Positive(t, top.TotalCompute()) must.Positive(t, top.NumCores()) diff --git a/client/pluginmanager/drivermanager/testing.go b/client/pluginmanager/drivermanager/testing.go index d20b508c8..647a088b5 100644 --- a/client/pluginmanager/drivermanager/testing.go +++ b/client/pluginmanager/drivermanager/testing.go @@ -27,7 +27,7 @@ type testManager struct { } func TestDriverManager(t *testing.T) Manager { - topology := numalib.Scan(numalib.PlatformScanners()) + topology := numalib.Scan(numalib.PlatformScanners(false)) logger := testlog.HCLogger(t).Named("driver_mgr") pluginLoader := catalog.TestPluginLoader(t) return &testManager{ diff --git a/command/agent/agent.go b/command/agent/agent.go index 2dc97e5b0..d9bbe78c0 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -755,6 +755,9 @@ func convertClientConfig(agentConfig *Config) (*clientconfig.Config, error) { if agentConfig.Client.NetworkSpeed != 0 { conf.NetworkSpeed = agentConfig.Client.NetworkSpeed } + if agentConfig.Client.CpuDisableDmidecode { + conf.CpuDisableDmidecode = agentConfig.Client.CpuDisableDmidecode + } if agentConfig.Client.CpuCompute != 0 { conf.CpuCompute = agentConfig.Client.CpuCompute } diff --git a/command/agent/config.go b/command/agent/config.go index 0e0f82f46..1e2dbb3c5 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -275,6 +275,9 @@ type ClientConfig struct { // speed. NetworkSpeed int `hcl:"network_speed"` + // CpuDisableDmidecode is used to disable dmidecode usage for CPU calculation + CpuDisableDmidecode bool `hcl:"cpu_disable_dmidecode"` + // CpuCompute is used to override any detected or default total CPU compute. CpuCompute int `hcl:"cpu_total_compute"` @@ -2346,6 +2349,9 @@ func (a *ClientConfig) Merge(b *ClientConfig) *ClientConfig { if b.NetworkSpeed != 0 { result.NetworkSpeed = b.NetworkSpeed } + if b.CpuDisableDmidecode { + result.CpuDisableDmidecode = b.CpuDisableDmidecode + } if b.CpuCompute != 0 { result.CpuCompute = b.CpuCompute } diff --git a/drivers/docker/driver_test.go b/drivers/docker/driver_test.go index 77437f819..43649aebe 100644 --- a/drivers/docker/driver_test.go +++ b/drivers/docker/driver_test.go @@ -68,7 +68,7 @@ var ( ) var ( - top = numalib.Scan(numalib.PlatformScanners()) + top = numalib.Scan(numalib.PlatformScanners(false)) ) func dockerIsRemote() bool { diff --git a/drivers/docker/fingerprint_test.go b/drivers/docker/fingerprint_test.go index fbdf147ec..4f88241eb 100644 --- a/drivers/docker/fingerprint_test.go +++ b/drivers/docker/fingerprint_test.go @@ -16,7 +16,7 @@ import ( ) var ( - topology = numalib.Scan(numalib.PlatformScanners()) + topology = numalib.Scan(numalib.PlatformScanners(false)) ) // TestDockerDriver_FingerprintHealth asserts that docker reports healthy diff --git a/drivers/exec/driver_test.go b/drivers/exec/driver_test.go index 7183ad8bf..59a3ac606 100644 --- a/drivers/exec/driver_test.go +++ b/drivers/exec/driver_test.go @@ -75,7 +75,7 @@ func testResources(allocID, task string) *drivers.Resources { } func newExecDriverTest(t *testing.T, ctx context.Context) drivers.DriverPlugin { - topology := numalib.Scan(numalib.PlatformScanners()) + topology := numalib.Scan(numalib.PlatformScanners(false)) d := NewExecDriver(ctx, testlog.HCLogger(t)) d.(*Driver).nomadConfig = &base.ClientDriverConfig{Topology: topology} d.(*Driver).userIDValidator = &mockIDValidator{} diff --git a/drivers/java/driver_test.go b/drivers/java/driver_test.go index 35c467f94..03857615a 100644 --- a/drivers/java/driver_test.go +++ b/drivers/java/driver_test.go @@ -39,7 +39,7 @@ func javaCompatible(t *testing.T) { } func newJavaDriverTest(t *testing.T, ctx context.Context) drivers.DriverPlugin { - topology := numalib.Scan(numalib.PlatformScanners()) + topology := numalib.Scan(numalib.PlatformScanners(false)) d := NewDriver(ctx, testlog.HCLogger(t)) d.(*Driver).nomadConfig = &base.ClientDriverConfig{Topology: topology} return d diff --git a/drivers/qemu/driver_test.go b/drivers/qemu/driver_test.go index 7148760ae..936898cfe 100644 --- a/drivers/qemu/driver_test.go +++ b/drivers/qemu/driver_test.go @@ -38,7 +38,7 @@ func TestQemuDriver_Start_Wait_Stop(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - topology := numalib.Scan(numalib.PlatformScanners()) + topology := numalib.Scan(numalib.PlatformScanners(false)) d := NewQemuDriver(ctx, testlog.HCLogger(t)) d.(*Driver).nomadConfig = &base.ClientDriverConfig{Topology: topology} harness := dtestutil.NewDriverHarness(t, d) @@ -116,7 +116,7 @@ func TestQemuDriver_User(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - topology := numalib.Scan(numalib.PlatformScanners()) + topology := numalib.Scan(numalib.PlatformScanners(false)) d := NewQemuDriver(ctx, testlog.HCLogger(t)) d.(*Driver).nomadConfig = &base.ClientDriverConfig{Topology: topology} harness := dtestutil.NewDriverHarness(t, d) @@ -161,7 +161,7 @@ func TestQemuDriver_Stats(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - topology := numalib.Scan(numalib.PlatformScanners()) + topology := numalib.Scan(numalib.PlatformScanners(false)) d := NewQemuDriver(ctx, testlog.HCLogger(t)) d.(*Driver).nomadConfig = &base.ClientDriverConfig{Topology: topology} harness := dtestutil.NewDriverHarness(t, d) diff --git a/drivers/rawexec/driver_test.go b/drivers/rawexec/driver_test.go index 887367ae7..78d60e2fa 100644 --- a/drivers/rawexec/driver_test.go +++ b/drivers/rawexec/driver_test.go @@ -73,7 +73,7 @@ func TestMain(m *testing.M) { } var ( - topology = numalib.Scan(numalib.PlatformScanners()) + topology = numalib.Scan(numalib.PlatformScanners(false)) ) type mockIDValidator struct{} diff --git a/drivers/shared/executor/executor_test.go b/drivers/shared/executor/executor_test.go index 6c21a9a9a..4122dcff0 100644 --- a/drivers/shared/executor/executor_test.go +++ b/drivers/shared/executor/executor_test.go @@ -55,7 +55,7 @@ func init() { } var ( - topology = numalib.Scan(numalib.PlatformScanners()) + topology = numalib.Scan(numalib.PlatformScanners(false)) compute = topology.Compute() ) @@ -341,7 +341,7 @@ func TestExecutor_Shutdown_Exit(t *testing.T) { } driverCfg := &base.ClientDriverConfig{ - Topology: numalib.Scan(numalib.PlatformScanners()), + Topology: numalib.Scan(numalib.PlatformScanners(false)), } executor, pluginClient, err := CreateExecutor(testlog.HCLogger(t), driverCfg, cfg) diff --git a/drivers/shared/executor/executor_windows_test.go b/drivers/shared/executor/executor_windows_test.go index c54cd4972..b1d8d6ae8 100644 --- a/drivers/shared/executor/executor_windows_test.go +++ b/drivers/shared/executor/executor_windows_test.go @@ -61,7 +61,7 @@ func testExecutorCommand(t *testing.T) *testExecCmd { func TestExecutor_ProcessExit(t *testing.T) { ci.Parallel(t) - topology := numalib.Scan(numalib.PlatformScanners()) + topology := numalib.Scan(numalib.PlatformScanners(false)) compute := topology.Compute() cmd := testExecutorCommand(t) diff --git a/website/content/docs/configuration/client.mdx b/website/content/docs/configuration/client.mdx index de740eb31..4d0a6de3d 100644 --- a/website/content/docs/configuration/client.mdx +++ b/website/content/docs/configuration/client.mdx @@ -78,6 +78,9 @@ client { the preferred family. When the option is not specified, the current behavior is conserved: the first IP address is selected no matter the family. +- `cpu_disable_dmidecode` `(bool: false)` - Specifies the client should not use dmidecode + as a method of cpu detection. Nomad ignores this field on all platforms except Linux. + - `cpu_total_compute` `(int: 0)` - Specifies an override for the total CPU compute. This value should be set to `# Cores * Core MHz`. For example, a quad-core running at 2 GHz would have a total compute of 8000 (4 \* 2000). Most