fingerprint: add node attr for reserverable cores (#14694)

* fingerprint: add node attr for reserverable cores

Add an attribute for the number of reservable CPU cores as they may
differ from the existing `cpu.numcores` due to client configuration or
OS support.

Hopefully clarifies some confusion in #14676

* add changelog

* num_reservable_cores -> reservablecores
This commit is contained in:
Michael Schurter 2022-09-26 13:03:03 -07:00 committed by GitHub
parent 5c100c0d3d
commit e6af1c0a14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 3 deletions

3
.changelog/14694.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
fingerprint: Add node attribute for number of reservable cores: `cpu.num_reservable_cores`
```

View File

@ -2,6 +2,7 @@ package fingerprint
import ( import (
"fmt" "fmt"
"strconv"
"github.com/hashicorp/nomad/lib/cpuset" "github.com/hashicorp/nomad/lib/cpuset"
@ -62,7 +63,7 @@ func (f *CPUFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintR
var numCores int var numCores int
if numCores = stats.CPUNumCores(); numCores > 0 { if numCores = stats.CPUNumCores(); numCores > 0 {
resp.AddAttribute("cpu.numcores", fmt.Sprintf("%d", numCores)) resp.AddAttribute("cpu.numcores", strconv.Itoa(numCores))
f.logger.Debug("detected core count", "cores", numCores) f.logger.Debug("detected core count", "cores", numCores)
} }
@ -80,6 +81,7 @@ func (f *CPUFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintR
f.logger.Debug("detected reservable cores", "cpuset", reservableCores) f.logger.Debug("detected reservable cores", "cpuset", reservableCores)
} }
} }
resp.AddAttribute("cpu.reservablecores", strconv.Itoa(len(reservableCores)))
tt := int(stats.TotalTicksAvailable()) tt := int(stats.TotalTicksAvailable())
if cfg.CpuCompute > 0 { if cfg.CpuCompute > 0 {

View File

@ -67,7 +67,9 @@ func TestCPUFingerprint_OverrideCompute(t *testing.T) {
node := &structs.Node{ node := &structs.Node{
Attributes: make(map[string]string), Attributes: make(map[string]string),
} }
cfg := &config.Config{} cfg := &config.Config{
ReservableCores: []uint16{0, 1, 2},
}
var originalCPU int var originalCPU int
{ {
@ -82,6 +84,10 @@ func TestCPUFingerprint_OverrideCompute(t *testing.T) {
t.Fatalf("expected response to be applicable") t.Fatalf("expected response to be applicable")
} }
if attr := response.Attributes["cpu.reservablecores"]; attr != "3" {
t.Fatalf("expected cpu.reservablecores == 3 but found %s", attr)
}
if response.Resources.CPU == 0 { if response.Resources.CPU == 0 {
t.Fatalf("expected fingerprint of cpu of but found 0") t.Fatalf("expected fingerprint of cpu of but found 0")
} }
@ -111,5 +117,9 @@ func TestCPUFingerprint_OverrideCompute(t *testing.T) {
if response.Attributes["cpu.totalcompute"] != strconv.Itoa(cfg.CpuCompute) { if response.Attributes["cpu.totalcompute"] != strconv.Itoa(cfg.CpuCompute) {
t.Fatalf("expected override cpu.totalcompute of %d but found %s", cfg.CpuCompute, response.Attributes["cpu.totalcompute"]) t.Fatalf("expected override cpu.totalcompute of %d but found %s", cfg.CpuCompute, response.Attributes["cpu.totalcompute"])
} }
if attr := response.Attributes["cpu.reservablecores"]; attr != "3" {
t.Fatalf("expected cpu.reservablecores == 3 but found %s", attr)
}
} }
} }

View File

@ -169,7 +169,13 @@ Below is a table documenting common node properties:
<td> <td>
<code>{'${attr.cpu.numcores}'}</code> <code>{'${attr.cpu.numcores}'}</code>
</td> </td>
<td>Number of CPU cores on the client</td> <td>Number of CPU cores on the client. May differ from how many cores are available for reservation due to OS or configuration. See <code>cpu.reservablecores</code>.</td>
</tr>
<tr>
<td>
<code>{'${attr.cpu.reservablecores}'}</code>
</td>
<td>Number of CPU cores on the client avaible for scheduling. Number of cores used by the scheduler when placing work with <code>resources.cores</code> set.</td>
</tr> </tr>
<tr> <tr>
<td> <td>