feat: allow users to check cpu arch (#1644)

This commit is contained in:
Shubhag Saxena
2024-10-10 18:59:22 +05:30
committed by GitHub
parent 402d111745
commit 52efd167ad
4 changed files with 43 additions and 7 deletions

View File

@@ -63,7 +63,7 @@ func (a *AnalyzeHostCPU) Analyze(
return []*AnalyzeResult{&result}, nil
}
isMatch, err := compareHostCPUConditionalToActual(outcome.Fail.When, cpuInfo.LogicalCount, cpuInfo.PhysicalCount, cpuInfo.Flags)
isMatch, err := compareHostCPUConditionalToActual(outcome.Fail.When, cpuInfo.LogicalCount, cpuInfo.PhysicalCount, cpuInfo.Flags, cpuInfo.MachineArch)
if err != nil {
return nil, errors.Wrap(err, "failed to compare")
}
@@ -84,7 +84,7 @@ func (a *AnalyzeHostCPU) Analyze(
return []*AnalyzeResult{&result}, nil
}
isMatch, err := compareHostCPUConditionalToActual(outcome.Warn.When, cpuInfo.LogicalCount, cpuInfo.PhysicalCount, cpuInfo.Flags)
isMatch, err := compareHostCPUConditionalToActual(outcome.Warn.When, cpuInfo.LogicalCount, cpuInfo.PhysicalCount, cpuInfo.Flags, cpuInfo.MachineArch)
if err != nil {
return nil, errors.Wrap(err, "failed to compare")
}
@@ -105,7 +105,7 @@ func (a *AnalyzeHostCPU) Analyze(
return []*AnalyzeResult{&result}, nil
}
isMatch, err := compareHostCPUConditionalToActual(outcome.Pass.When, cpuInfo.LogicalCount, cpuInfo.PhysicalCount, cpuInfo.Flags)
isMatch, err := compareHostCPUConditionalToActual(outcome.Pass.When, cpuInfo.LogicalCount, cpuInfo.PhysicalCount, cpuInfo.Flags, cpuInfo.MachineArch)
if err != nil {
return nil, errors.Wrap(err, "failed to compare")
}
@@ -164,14 +164,19 @@ func doCompareHostCPUFlags(expected string, flags []string) (res bool, err error
return true, nil
}
func compareHostCPUConditionalToActual(conditional string, logicalCount int, physicalCount int, flags []string) (res bool, err error) {
func compareHostCPUConditionalToActual(conditional string, logicalCount int, physicalCount int, flags []string, machineArch string) (res bool, err error) {
compareLogical := false
comparePhysical := false
compareUnspecified := false
compareMachineArch := false
comparator := ""
desired := ""
/* When the conditional is in the format of "logical <comparator> <desired>"
example: when: "count < 2"
*/
parts := strings.Split(conditional, " ")
if len(parts) == 3 {
comparator = parts[1]
@@ -182,6 +187,8 @@ func compareHostCPUConditionalToActual(conditional string, logicalCount int, phy
comparePhysical = true
} else if strings.ToLower(parts[0]) == "count" {
compareUnspecified = true
} else if strings.ToLower(parts[0]) == "machinearch" {
compareMachineArch = true
}
} else if len(parts) == 2 {
compareUnspecified = true
@@ -199,7 +206,7 @@ func compareHostCPUConditionalToActual(conditional string, logicalCount int, phy
return doCompareHostCPUFlags(desired, flags)
}
if !compareLogical && !comparePhysical && !compareUnspecified {
if !compareLogical && !comparePhysical && !compareUnspecified && !compareMachineArch {
return false, errors.New("unable to parse conditional")
}
@@ -207,6 +214,8 @@ func compareHostCPUConditionalToActual(conditional string, logicalCount int, phy
return doCompareHostCPU(comparator, desired, logicalCount)
} else if comparePhysical {
return doCompareHostCPU(comparator, desired, physicalCount)
} else if compareMachineArch {
return doCompareMachineArch(comparator, desired, machineArch)
} else {
actual := logicalCount
if physicalCount > logicalCount {
@@ -217,6 +226,16 @@ func compareHostCPUConditionalToActual(conditional string, logicalCount int, phy
}
}
func doCompareMachineArch(operator string, desired string, actual string) (bool, error) {
switch operator {
case "=", "==", "===":
return actual == desired, nil
case "!=", "!==":
return actual != desired, nil
}
return false, errors.New("unknown operator")
}
func doCompareHostCPU(operator string, desired string, actual int) (bool, error) {
desiredInt, err := strconv.ParseInt(desired, 10, 64)
if err != nil {
@@ -234,6 +253,8 @@ func doCompareHostCPU(operator string, desired string, actual int) (bool, error)
return actual >= int(desiredInt), nil
case "=", "==", "===":
return actual == int(desiredInt), nil
case "!=", "!==":
return actual != int(desiredInt), nil
}
return false, errors.New("unknown operator")

View File

@@ -82,6 +82,7 @@ func Test_compareHostCPUConditionalToActual(t *testing.T) {
logicalCount int
physicalCount int
flags []string
machineArch string
expected bool
}{
{
@@ -164,12 +165,18 @@ func Test_compareHostCPUConditionalToActual(t *testing.T) {
flags: []string{"a", "b", "c", "d", "e"},
expected: true,
},
{
name: "machine arch matches",
when: "machineArch == x86_64",
machineArch: "x86_64",
expected: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
req := require.New(t)
actual, err := compareHostCPUConditionalToActual(test.when, test.logicalCount, test.physicalCount, test.flags)
actual, err := compareHostCPUConditionalToActual(test.when, test.logicalCount, test.physicalCount, test.flags, test.machineArch)
req.NoError(err)
assert.Equal(t, test.expected, actual)

View File

@@ -7,12 +7,14 @@ import (
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/host"
)
type CPUInfo struct {
LogicalCount int `json:"logicalCount"`
PhysicalCount int `json:"physicalCount"`
Flags []string `json:"flags"`
MachineArch string `json:"machineArch"`
}
const HostCPUPath = `host-collectors/system/cpu.json`
@@ -45,6 +47,11 @@ func (c *CollectHostCPU) Collect(progressChan chan<- interface{}) (map[string][]
}
cpuInfo.PhysicalCount = physicalCount
cpuInfo.MachineArch, err = host.KernelArch()
if err != nil {
return nil, errors.Wrap(err, "failed to fetch cpu architecture")
}
// XXX even though the cpu.Info() returns a slice per CPU it is way
// common to have the same flags for all CPUs. We consolidate them here
// so the output is a list of all different flags present in all CPUs.

View File

@@ -25,8 +25,9 @@ func TestCollectHostCPU_Collect(t *testing.T) {
require.NoError(t, err)
// Check if values exist. They will be different on different machines.
assert.Equal(t, 3, len(m))
assert.Equal(t, 4, len(m))
assert.Contains(t, m, "logicalCount")
assert.Contains(t, m, "physicalCount")
assert.Contains(t, m, "flags")
assert.Contains(t, m, "machineArch")
}