Skip to content

Commit 64ee9e5

Browse files
DexterYanbanjoh
andauthored
feat(nodeResources): add GPU support (#1708)
* feat(nodeResources): add GPU support * add resourceCapacity and sum test * update with make schemas * Correct tests names Signed-off-by: Evans Mungai <evans@replicated.com> --------- Signed-off-by: Evans Mungai <evans@replicated.com> Co-authored-by: Evans Mungai <evans@replicated.com>
1 parent 2772722 commit 64ee9e5

17 files changed

+784
-17
lines changed

config/crds/troubleshoot.replicated.com_analyzers.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ spec:
417417
type: string
418418
podCapacity:
419419
type: string
420+
resourceAllocatable:
421+
type: string
422+
resourceCapacity:
423+
type: string
424+
resourceName:
425+
type: string
420426
selector:
421427
properties:
422428
matchLabel:

config/crds/troubleshoot.replicated.com_preflights.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ spec:
417417
type: string
418418
podCapacity:
419419
type: string
420+
resourceAllocatable:
421+
type: string
422+
resourceCapacity:
423+
type: string
424+
resourceName:
425+
type: string
420426
selector:
421427
properties:
422428
matchLabel:

config/crds/troubleshoot.replicated.com_supportbundles.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,12 @@ spec:
448448
type: string
449449
podCapacity:
450450
type: string
451+
resourceAllocatable:
452+
type: string
453+
resourceCapacity:
454+
type: string
455+
resourceName:
456+
type: string
451457
selector:
452458
properties:
453459
matchLabel:

config/crds/troubleshoot.sh_analyzers.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,12 @@ spec:
12391239
type: string
12401240
podCapacity:
12411241
type: string
1242+
resourceAllocatable:
1243+
type: string
1244+
resourceCapacity:
1245+
type: string
1246+
resourceName:
1247+
type: string
12421248
selector:
12431249
properties:
12441250
matchExpressions:

config/crds/troubleshoot.sh_preflights.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,12 @@ spec:
12391239
type: string
12401240
podCapacity:
12411241
type: string
1242+
resourceAllocatable:
1243+
type: string
1244+
resourceCapacity:
1245+
type: string
1246+
resourceName:
1247+
type: string
12421248
selector:
12431249
properties:
12441250
matchExpressions:

config/crds/troubleshoot.sh_supportbundles.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,12 @@ spec:
12701270
type: string
12711271
podCapacity:
12721272
type: string
1273+
resourceAllocatable:
1274+
type: string
1275+
resourceCapacity:
1276+
type: string
1277+
resourceName:
1278+
type: string
12731279
selector:
12741280
properties:
12751281
matchExpressions:

pkg/analyze/files/nodes.json

Lines changed: 387 additions & 2 deletions
Large diffs are not rendered by default.

pkg/analyze/node_resources.go

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ func (a *AnalyzeNodeResources) analyzeNodeResources(analyzer *troubleshootv1beta
8585

8686
for _, outcome := range analyzer.Outcomes {
8787
if outcome.Fail != nil {
88-
isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Fail.When, matchingNodes)
88+
isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Fail.When, matchingNodes, analyzer.Filters)
89+
8990
if err != nil {
9091
return nil, errors.Wrap(err, "failed to parse when")
9192
}
@@ -100,7 +101,7 @@ func (a *AnalyzeNodeResources) analyzeNodeResources(analyzer *troubleshootv1beta
100101
return result, nil
101102
}
102103
} else if outcome.Warn != nil {
103-
isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Warn.When, matchingNodes)
104+
isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Warn.When, matchingNodes, analyzer.Filters)
104105
if err != nil {
105106
return nil, errors.Wrap(err, "failed to parse when")
106107
}
@@ -116,7 +117,7 @@ func (a *AnalyzeNodeResources) analyzeNodeResources(analyzer *troubleshootv1beta
116117
return result, nil
117118
}
118119
} else if outcome.Pass != nil {
119-
isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Pass.When, matchingNodes)
120+
isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Pass.When, matchingNodes, analyzer.Filters)
120121
if err != nil {
121122
return nil, errors.Wrap(err, "failed to parse when")
122123
}
@@ -137,7 +138,7 @@ func (a *AnalyzeNodeResources) analyzeNodeResources(analyzer *troubleshootv1beta
137138
return result, nil
138139
}
139140

140-
func compareNodeResourceConditionalToActual(conditional string, matchingNodes []corev1.Node) (res bool, err error) {
141+
func compareNodeResourceConditionalToActual(conditional string, matchingNodes []corev1.Node, filters *troubleshootv1beta2.NodeResourceFilters) (res bool, err error) {
141142
res = false
142143
err = nil
143144

@@ -190,18 +191,23 @@ func compareNodeResourceConditionalToActual(conditional string, matchingNodes []
190191

191192
function := match[1]
192193
property := match[2]
194+
resourceName := ""
195+
196+
if filters != nil {
197+
resourceName = filters.ResourceName
198+
}
193199

194200
var actualValue interface{}
195201

196202
switch function {
197203
case "count":
198204
actualValue = len(matchingNodes)
199205
case "min":
200-
actualValue = findMin(matchingNodes, property)
206+
actualValue = findMin(matchingNodes, property, resourceName)
201207
case "max":
202-
actualValue = findMax(matchingNodes, property)
208+
actualValue = findMax(matchingNodes, property, resourceName)
203209
case "sum":
204-
actualValue = findSum(matchingNodes, property)
210+
actualValue = findSum(matchingNodes, property, resourceName)
205211
case "nodeCondition":
206212
operatorChecker := regexp.MustCompile(`={1,3}`)
207213
if !operatorChecker.MatchString(operator) {
@@ -311,7 +317,7 @@ func compareNodeResourceConditionalToActual(conditional string, matchingNodes []
311317
return
312318
}
313319

314-
func getQuantity(node corev1.Node, property string) *resource.Quantity {
320+
func getQuantity(node corev1.Node, property string, resourceName string) *resource.Quantity {
315321
switch property {
316322
case "cpuCapacity":
317323
return node.Status.Capacity.Cpu()
@@ -329,27 +335,39 @@ func getQuantity(node corev1.Node, property string) *resource.Quantity {
329335
return node.Status.Capacity.StorageEphemeral()
330336
case "ephemeralStorageAllocatable":
331337
return node.Status.Allocatable.StorageEphemeral()
338+
case "resourceCapacity":
339+
capacity, ok := node.Status.Capacity[corev1.ResourceName(resourceName)]
340+
if !ok {
341+
return nil
342+
}
343+
return &capacity
344+
case "resourceAllocatable":
345+
allocatable, ok := node.Status.Allocatable[corev1.ResourceName(resourceName)]
346+
if !ok {
347+
return nil
348+
}
349+
return &allocatable
332350
}
333351
return nil
334352
}
335353

336-
func findSum(nodes []corev1.Node, property string) *resource.Quantity {
354+
func findSum(nodes []corev1.Node, property string, resourceName string) *resource.Quantity {
337355
sum := resource.Quantity{}
338356

339357
for _, node := range nodes {
340-
if quant := getQuantity(node, property); quant != nil {
358+
if quant := getQuantity(node, property, resourceName); quant != nil {
341359
sum.Add(*quant)
342360
}
343361
}
344362

345363
return &sum
346364
}
347365

348-
func findMin(nodes []corev1.Node, property string) *resource.Quantity {
366+
func findMin(nodes []corev1.Node, property string, resourceName string) *resource.Quantity {
349367
var min *resource.Quantity
350368

351369
for _, node := range nodes {
352-
if quant := getQuantity(node, property); quant != nil {
370+
if quant := getQuantity(node, property, resourceName); quant != nil {
353371
if min == nil {
354372
min = quant
355373
} else if quant.Cmp(*min) == -1 {
@@ -361,11 +379,11 @@ func findMin(nodes []corev1.Node, property string) *resource.Quantity {
361379
return min
362380
}
363381

364-
func findMax(nodes []corev1.Node, property string) *resource.Quantity {
382+
func findMax(nodes []corev1.Node, property string, resourceName string) *resource.Quantity {
365383
var max *resource.Quantity
366384

367385
for _, node := range nodes {
368-
if quant := getQuantity(node, property); quant != nil {
386+
if quant := getQuantity(node, property, resourceName); quant != nil {
369387
if max == nil {
370388
max = quant
371389
} else if quant.Cmp(*max) == 1 {
@@ -382,6 +400,39 @@ func nodeMatchesFilters(node corev1.Node, filters *troubleshootv1beta2.NodeResou
382400
return true, nil
383401
}
384402

403+
if filters.ResourceName != "" {
404+
capacity, capacityExists := node.Status.Capacity[corev1.ResourceName(filters.ResourceName)]
405+
allocatable, allocatableExists := node.Status.Allocatable[corev1.ResourceName(filters.ResourceName)]
406+
407+
if !capacityExists && !allocatableExists {
408+
return false, nil
409+
}
410+
411+
if filters.ResourceCapacity != "" {
412+
parsed, err := resource.ParseQuantity(filters.ResourceCapacity)
413+
if err != nil {
414+
return false, errors.Wrap(err, "failed to parse resource capacity")
415+
}
416+
417+
// Compare the capacity value with the parsed value
418+
if capacity.Cmp(parsed) == -1 {
419+
return false, nil
420+
}
421+
}
422+
423+
if filters.ResourceAllocatable != "" {
424+
parsed, err := resource.ParseQuantity(filters.ResourceAllocatable)
425+
if err != nil {
426+
return false, errors.Wrap(err, "failed to parse resource allocatable")
427+
}
428+
429+
// Compare the allocatable value with the parsed value
430+
if allocatable.Cmp(parsed) == -1 {
431+
return false, nil
432+
}
433+
}
434+
}
435+
385436
// all filters must pass for this to pass
386437
if filters.Selector != nil {
387438
selector, err := metav1.LabelSelectorAsSelector(

0 commit comments

Comments
 (0)