1package api 2 3import ( 4 "strconv" 5) 6 7// Resources encapsulates the required resources of 8// a given task or task group. 9type Resources struct { 10 CPU *int 11 MemoryMB *int `mapstructure:"memory"` 12 DiskMB *int `mapstructure:"disk"` 13 Networks []*NetworkResource 14 Devices []*RequestedDevice 15 16 // COMPAT(0.10) 17 // XXX Deprecated. Please do not use. The field will be removed in Nomad 18 // 0.10 and is only being kept to allow any references to be removed before 19 // then. 20 IOPS *int 21} 22 23// Canonicalize will supply missing values in the cases 24// where they are not provided. 25func (r *Resources) Canonicalize() { 26 defaultResources := DefaultResources() 27 if r.CPU == nil { 28 r.CPU = defaultResources.CPU 29 } 30 if r.MemoryMB == nil { 31 r.MemoryMB = defaultResources.MemoryMB 32 } 33 for _, n := range r.Networks { 34 n.Canonicalize() 35 } 36 for _, d := range r.Devices { 37 d.Canonicalize() 38 } 39} 40 41// DefaultResources is a small resources object that contains the 42// default resources requests that we will provide to an object. 43// --- THIS FUNCTION IS REPLICATED IN nomad/structs/structs.go 44// and should be kept in sync. 45func DefaultResources() *Resources { 46 return &Resources{ 47 CPU: intToPtr(100), 48 MemoryMB: intToPtr(300), 49 } 50} 51 52// MinResources is a small resources object that contains the 53// absolute minimum resources that we will provide to an object. 54// This should not be confused with the defaults which are 55// provided in DefaultResources() --- THIS LOGIC IS REPLICATED 56// IN nomad/structs/structs.go and should be kept in sync. 57func MinResources() *Resources { 58 return &Resources{ 59 CPU: intToPtr(20), 60 MemoryMB: intToPtr(10), 61 } 62} 63 64// Merge merges this resource with another resource. 65func (r *Resources) Merge(other *Resources) { 66 if other == nil { 67 return 68 } 69 if other.CPU != nil { 70 r.CPU = other.CPU 71 } 72 if other.MemoryMB != nil { 73 r.MemoryMB = other.MemoryMB 74 } 75 if other.DiskMB != nil { 76 r.DiskMB = other.DiskMB 77 } 78 if len(other.Networks) != 0 { 79 r.Networks = other.Networks 80 } 81 if len(other.Devices) != 0 { 82 r.Devices = other.Devices 83 } 84} 85 86type Port struct { 87 Label string 88 Value int `mapstructure:"static"` 89} 90 91// NetworkResource is used to describe required network 92// resources of a given task. 93type NetworkResource struct { 94 Device string 95 CIDR string 96 IP string 97 MBits *int 98 ReservedPorts []Port 99 DynamicPorts []Port 100} 101 102func (n *NetworkResource) Canonicalize() { 103 if n.MBits == nil { 104 n.MBits = intToPtr(10) 105 } 106} 107 108// NodeDeviceResource captures a set of devices sharing a common 109// vendor/type/device_name tuple. 110type NodeDeviceResource struct { 111 112 // Vendor specifies the vendor of device 113 Vendor string 114 115 // Type specifies the type of the device 116 Type string 117 118 // Name specifies the specific model of the device 119 Name string 120 121 // Instances are list of the devices matching the vendor/type/name 122 Instances []*NodeDevice 123 124 Attributes map[string]*Attribute 125} 126 127func (r NodeDeviceResource) ID() string { 128 return r.Vendor + "/" + r.Type + "/" + r.Name 129} 130 131// NodeDevice is an instance of a particular device. 132type NodeDevice struct { 133 // ID is the ID of the device. 134 ID string 135 136 // Healthy captures whether the device is healthy. 137 Healthy bool 138 139 // HealthDescription is used to provide a human readable description of why 140 // the device may be unhealthy. 141 HealthDescription string 142 143 // Locality stores HW locality information for the node to optionally be 144 // used when making placement decisions. 145 Locality *NodeDeviceLocality 146} 147 148// Attribute is used to describe the value of an attribute, optionally 149// specifying units 150type Attribute struct { 151 // Float is the float value for the attribute 152 FloatVal *float64 `json:"Float,omitempty"` 153 154 // Int is the int value for the attribute 155 IntVal *int64 `json:"Int,omitempty"` 156 157 // String is the string value for the attribute 158 StringVal *string `json:"String,omitempty"` 159 160 // Bool is the bool value for the attribute 161 BoolVal *bool `json:"Bool,omitempty"` 162 163 // Unit is the optional unit for the set int or float value 164 Unit string 165} 166 167func (a Attribute) String() string { 168 switch { 169 case a.FloatVal != nil: 170 str := formatFloat(*a.FloatVal, 3) 171 if a.Unit != "" { 172 str += " " + a.Unit 173 } 174 return str 175 case a.IntVal != nil: 176 str := strconv.FormatInt(*a.IntVal, 10) 177 if a.Unit != "" { 178 str += " " + a.Unit 179 } 180 return str 181 case a.StringVal != nil: 182 return *a.StringVal 183 case a.BoolVal != nil: 184 return strconv.FormatBool(*a.BoolVal) 185 default: 186 return "<unknown>" 187 } 188} 189 190// NodeDeviceLocality stores information about the devices hardware locality on 191// the node. 192type NodeDeviceLocality struct { 193 // PciBusID is the PCI Bus ID for the device. 194 PciBusID string 195} 196 197// RequestedDevice is used to request a device for a task. 198type RequestedDevice struct { 199 // Name is the request name. The possible values are as follows: 200 // * <type>: A single value only specifies the type of request. 201 // * <vendor>/<type>: A single slash delimiter assumes the vendor and type of device is specified. 202 // * <vendor>/<type>/<name>: Two slash delimiters assume vendor, type and specific model are specified. 203 // 204 // Examples are as follows: 205 // * "gpu" 206 // * "nvidia/gpu" 207 // * "nvidia/gpu/GTX2080Ti" 208 Name string 209 210 // Count is the number of requested devices 211 Count *uint64 212 213 // Constraints are a set of constraints to apply when selecting the device 214 // to use. 215 Constraints []*Constraint 216 217 // Affinities are a set of affinites to apply when selecting the device 218 // to use. 219 Affinities []*Affinity 220} 221 222func (d *RequestedDevice) Canonicalize() { 223 if d.Count == nil { 224 d.Count = uint64ToPtr(1) 225 } 226 227 for _, a := range d.Affinities { 228 a.Canonicalize() 229 } 230} 231