github.com/hernad/nomad@v1.6.112/command/helper_devices.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package command 5 6 import ( 7 "fmt" 8 "sort" 9 10 "github.com/hernad/nomad/api" 11 "github.com/mitchellh/cli" 12 ) 13 14 func deviceQualifiedID(vendor, typ, name, id string) string { 15 p := vendor 16 if typ != "" { 17 p += "/" + typ 18 } 19 if name != "" { 20 p += "/" + name 21 } 22 23 return p + "[" + id + "]" 24 } 25 26 func buildDeviceStatsSummaryMap(deviceGroupStats []*api.DeviceGroupStats) map[string]*api.StatValue { 27 r := map[string]*api.StatValue{} 28 29 for _, dg := range deviceGroupStats { 30 for id, stats := range dg.InstanceStats { 31 k := deviceQualifiedID(dg.Vendor, dg.Type, dg.Name, id) 32 r[k] = stats.Summary 33 } 34 } 35 36 return r 37 } 38 39 func formatDeviceStats(qid string, stat *api.StatObject) []string { 40 attrs := []string{fmt.Sprintf("Device|%s", qid)} 41 formatDeviceStatsImpl(stat, "", &attrs) 42 43 sort.Strings(attrs[1:]) 44 45 return attrs 46 } 47 48 func formatDeviceStatsImpl(stat *api.StatObject, keyPrefix string, result *[]string) { 49 if keyPrefix != "" { 50 keyPrefix = keyPrefix + "." 51 } 52 53 for n, stat := range stat.Attributes { 54 *result = append(*result, fmt.Sprintf("%s%s|%s", keyPrefix, n, stat)) 55 } 56 57 for k, o := range stat.Nested { 58 formatDeviceStatsImpl(o, keyPrefix+k, result) 59 } 60 } 61 62 // getDeviceResourcesForNode returns a list of devices and their statistics summary 63 // and tracks devices without statistics 64 func getDeviceResourcesForNode(deviceGroupStats []*api.DeviceGroupStats, node *api.Node) []string { 65 statsSummaryMap := buildDeviceStatsSummaryMap(deviceGroupStats) 66 67 devices := []string{} 68 for _, dg := range node.NodeResources.Devices { 69 for _, inst := range dg.Instances { 70 id := deviceQualifiedID(dg.Vendor, dg.Type, dg.Name, inst.ID) 71 statStr := "" 72 if stats, ok := statsSummaryMap[id]; ok && stats != nil { 73 statStr = stats.String() 74 } 75 76 devices = append(devices, fmt.Sprintf("%v|%v", id, statStr)) 77 } 78 } 79 80 sort.Strings(devices) 81 82 return devices 83 } 84 85 // getDeviceResources returns alist of devices and their statistics summary 86 func getDeviceResources(deviceGroupStats []*api.DeviceGroupStats) []string { 87 statsSummaryMap := buildDeviceStatsSummaryMap(deviceGroupStats) 88 89 result := make([]string, 0, len(statsSummaryMap)) 90 for id, stats := range statsSummaryMap { 91 result = append(result, id+"|"+stats.String()) 92 } 93 94 sort.Strings(result) 95 96 return result 97 } 98 99 func printDeviceStats(ui cli.Ui, deviceGroupStats []*api.DeviceGroupStats) { 100 isFirst := true 101 for _, dg := range deviceGroupStats { 102 for id, dinst := range dg.InstanceStats { 103 if !isFirst { 104 ui.Output("") 105 } 106 isFirst = false 107 108 qid := deviceQualifiedID(dg.Vendor, dg.Type, dg.Name, id) 109 attrs := formatDeviceStats(qid, dinst.Stats) 110 111 ui.Output(formatKV(attrs)) 112 } 113 } 114 } 115 116 func getDeviceAttributes(d *api.NodeDeviceResource) []string { 117 attrs := []string{fmt.Sprintf("Device Group|%s", d.ID())} 118 119 for k, v := range d.Attributes { 120 attrs = append(attrs, k+"|"+v.String()) 121 } 122 123 sort.Strings(attrs[1:]) 124 125 return attrs 126 }