diff --git a/devices/gpu/nvidia/fingerprint.go b/devices/gpu/nvidia/fingerprint.go index 15e2e9c4a..f8adcab9e 100644 --- a/devices/gpu/nvidia/fingerprint.go +++ b/devices/gpu/nvidia/fingerprint.go @@ -2,24 +2,25 @@ package nvidia import ( "context" - "fmt" "time" "github.com/hashicorp/nomad/devices/gpu/nvidia/nvml" + "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/plugins/device" + "github.com/hashicorp/nomad/plugins/shared/structs" ) const ( - // Attribute names for reporting Fingerprint output - MemoryMiBAttr = "memory_mib" - PowerWAttr = "power_w" - BAR1MiBAttr = "bar1_mib" - DriverVersionAttr = "driver_version" - CoresClockMHzAttr = "cores_clock_mhz" - MemoryClockMHzAttr = "memory_clock_mhz" - PCIBandwidthMBPerSAttr = "pci_bandwidth_mb/s" - DisplayStateAttr = "display_state" - PersistenceModeAttr = "persistence_mode" + // Attribute names and units for reporting Fingerprint output + MemoryAttr = "memory" + PowerAttr = "power" + BAR1Attr = "bar1" + DriverVersionAttr = "driver_version" + CoresClockAttr = "cores_clock" + MemoryClockAttr = "memory_clock" + PCIBandwidthAttr = "pci_bandwidth" + DisplayStateAttr = "display_state" + PersistenceModeAttr = "persistence_mode" ) // fingerprint is the long running goroutine that detects hardware @@ -69,8 +70,10 @@ func (d *NvidiaDevice) writeFingerprintToChannel(devices chan<- *device.Fingerpr return } - commonAttributes := map[string]string{ - DriverVersionAttr: fingerprintData.DriverVersion, + commonAttributes := map[string]*structs.Attribute{ + DriverVersionAttr: { + String: helper.StringToPtr(fingerprintData.DriverVersion), + }, } // Group all FingerprintDevices by DeviceName attribute @@ -137,7 +140,7 @@ func (d *NvidiaDevice) fingerprintChanged(allDevices []*nvml.FingerprintDeviceDa } // deviceGroupFromFingerprintData composes deviceGroup from FingerprintDeviceData slice -func deviceGroupFromFingerprintData(groupName string, deviceList []*nvml.FingerprintDeviceData, commonAttributes map[string]string) *device.DeviceGroup { +func deviceGroupFromFingerprintData(groupName string, deviceList []*nvml.FingerprintDeviceData, commonAttributes map[string]*structs.Attribute) *device.DeviceGroup { // deviceGroup without devices makes no sense -> return nil when no devices are provided if len(deviceList) == 0 { return nil @@ -177,63 +180,52 @@ func deviceGroupFromFingerprintData(groupName string, deviceList []*nvml.Fingerp // attributesFromFingerprintDeviceData converts nvml.FingerprintDeviceData // struct to device.DeviceGroup.Attributes format (map[string]string) // this function performs all nil checks for FingerprintDeviceData pointers -func attributesFromFingerprintDeviceData(fingerprintDeviceData *nvml.FingerprintDeviceData) map[string]string { - // The following fields in FingerprintDeviceData are pointers, so they can be nil - // In case they are nil -> return 'notAvailable' constant instead - var ( - MemoryMiB string - PowerW string - BAR1MiB string - CoresClockMHz string - MemoryClockMHz string - PCIBandwidthMBPerS string - ) - - if fingerprintDeviceData.MemoryMiB == nil { - MemoryMiB = notAvailable - } else { - MemoryMiB = fmt.Sprint(*fingerprintDeviceData.MemoryMiB) +func attributesFromFingerprintDeviceData(d *nvml.FingerprintDeviceData) map[string]*structs.Attribute { + attrs := map[string]*structs.Attribute{ + DisplayStateAttr: { + String: helper.StringToPtr(d.DisplayState), + }, + PersistenceModeAttr: { + String: helper.StringToPtr(d.PersistenceMode), + }, } - if fingerprintDeviceData.PowerW == nil { - PowerW = notAvailable - } else { - PowerW = fmt.Sprint(*fingerprintDeviceData.PowerW) - } - - if fingerprintDeviceData.BAR1MiB == nil { - BAR1MiB = notAvailable - } else { - BAR1MiB = fmt.Sprint(*fingerprintDeviceData.BAR1MiB) - } - - if fingerprintDeviceData.CoresClockMHz == nil { - CoresClockMHz = notAvailable - } else { - CoresClockMHz = fmt.Sprint(*fingerprintDeviceData.CoresClockMHz) - } - - if fingerprintDeviceData.MemoryClockMHz == nil { - MemoryClockMHz = notAvailable - } else { - MemoryClockMHz = fmt.Sprint(*fingerprintDeviceData.MemoryClockMHz) - } - - if fingerprintDeviceData.PCIBandwidthMBPerS == nil { - PCIBandwidthMBPerS = notAvailable - } else { - PCIBandwidthMBPerS = fmt.Sprint(*fingerprintDeviceData.PCIBandwidthMBPerS) - } - - return map[string]string{ - DisplayStateAttr: fingerprintDeviceData.DisplayState, - PersistenceModeAttr: fingerprintDeviceData.PersistenceMode, - MemoryMiBAttr: MemoryMiB, - PowerWAttr: PowerW, - BAR1MiBAttr: BAR1MiB, - CoresClockMHzAttr: CoresClockMHz, - MemoryClockMHzAttr: MemoryClockMHz, - PCIBandwidthMBPerSAttr: PCIBandwidthMBPerS, + if d.MemoryMiB != nil { + attrs[MemoryAttr] = &structs.Attribute{ + Int: helper.Int64ToPtr(int64(*d.MemoryMiB)), + Unit: structs.UnitMiB, + } + } + if d.PowerW != nil { + attrs[PowerAttr] = &structs.Attribute{ + Int: helper.Int64ToPtr(int64(*d.PowerW)), + Unit: structs.UnitW, + } + } + if d.BAR1MiB != nil { + attrs[BAR1Attr] = &structs.Attribute{ + Int: helper.Int64ToPtr(int64(*d.BAR1MiB)), + Unit: structs.UnitMiB, + } + } + if d.CoresClockMHz != nil { + attrs[CoresClockAttr] = &structs.Attribute{ + Int: helper.Int64ToPtr(int64(*d.CoresClockMHz)), + Unit: structs.UnitMHz, + } + } + if d.MemoryClockMHz != nil { + attrs[MemoryClockAttr] = &structs.Attribute{ + Int: helper.Int64ToPtr(int64(*d.MemoryClockMHz)), + Unit: structs.UnitMHz, + } + } + if d.PCIBandwidthMBPerS != nil { + attrs[PCIBandwidthAttr] = &structs.Attribute{ + Int: helper.Int64ToPtr(int64(*d.PCIBandwidthMBPerS)), + Unit: structs.UnitMBPerS, + } } + return attrs } diff --git a/devices/gpu/nvidia/fingerprint_test.go b/devices/gpu/nvidia/fingerprint_test.go index b957d871f..c85b5c8c9 100644 --- a/devices/gpu/nvidia/fingerprint_test.go +++ b/devices/gpu/nvidia/fingerprint_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/nomad/devices/gpu/nvidia/nvml" "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/plugins/device" + "github.com/hashicorp/nomad/plugins/shared/structs" "github.com/stretchr/testify/require" ) @@ -359,7 +360,7 @@ func TestAttributesFromFingerprintDeviceData(t *testing.T) { for _, testCase := range []struct { Name string FingerprintDeviceData *nvml.FingerprintDeviceData - ExpectedResult map[string]string + ExpectedResult map[string]*structs.Attribute }{ { Name: "All attributes are not nil", @@ -378,19 +379,41 @@ func TestAttributesFromFingerprintDeviceData(t *testing.T) { DisplayState: "Enabled", PersistenceMode: "Enabled", }, - ExpectedResult: map[string]string{ - MemoryMiBAttr: "256", - PowerWAttr: "2", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + ExpectedResult: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(2), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, }, }, { - Name: "MemoryMiB is nil and has to be replaced to N/A", + Name: "nil values are omitted", FingerprintDeviceData: &nvml.FingerprintDeviceData{ DeviceData: &nvml.DeviceData{ UUID: "1", @@ -399,168 +422,31 @@ func TestAttributesFromFingerprintDeviceData(t *testing.T) { PowerW: helper.UintToPtr(2), BAR1MiB: helper.Uint64ToPtr(256), }, - PCIBusID: "pciBusID1", - PCIBandwidthMBPerS: helper.UintToPtr(1), - CoresClockMHz: helper.UintToPtr(1), - MemoryClockMHz: helper.UintToPtr(1), - DisplayState: "Enabled", - PersistenceMode: "Enabled", + PCIBusID: "pciBusID1", + DisplayState: "Enabled", + PersistenceMode: "Enabled", }, - ExpectedResult: map[string]string{ - MemoryMiBAttr: notAvailable, - PowerWAttr: "2", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", - }, - }, - { - Name: "PowerW is nil and has to be replaced to N/A", - FingerprintDeviceData: &nvml.FingerprintDeviceData{ - DeviceData: &nvml.DeviceData{ - UUID: "1", - DeviceName: helper.StringToPtr("Type1"), - MemoryMiB: helper.Uint64ToPtr(256), - PowerW: nil, - BAR1MiB: helper.Uint64ToPtr(256), + ExpectedResult: map[string]*structs.Attribute{ + PowerAttr: { + Int: helper.Int64ToPtr(2), + Unit: structs.UnitW, }, - PCIBusID: "pciBusID1", - PCIBandwidthMBPerS: helper.UintToPtr(1), - CoresClockMHz: helper.UintToPtr(1), - MemoryClockMHz: helper.UintToPtr(1), - DisplayState: "Enabled", - PersistenceMode: "Enabled", - }, - ExpectedResult: map[string]string{ - MemoryMiBAttr: "256", - PowerWAttr: notAvailable, - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", - }, - }, - { - Name: "BAR1MiB is nil and has to be replaced to N/A", - FingerprintDeviceData: &nvml.FingerprintDeviceData{ - DeviceData: &nvml.DeviceData{ - UUID: "1", - DeviceName: helper.StringToPtr("Type1"), - MemoryMiB: helper.Uint64ToPtr(256), - PowerW: helper.UintToPtr(2), - BAR1MiB: nil, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, }, - PCIBusID: "pciBusID1", - PCIBandwidthMBPerS: helper.UintToPtr(1), - CoresClockMHz: helper.UintToPtr(1), - MemoryClockMHz: helper.UintToPtr(1), - DisplayState: "Enabled", - PersistenceMode: "Enabled", - }, - ExpectedResult: map[string]string{ - MemoryMiBAttr: "256", - PowerWAttr: "2", - BAR1MiBAttr: notAvailable, - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", - }, - }, - { - Name: "PCIBandwidthMBPerS is nil and has to be replaced to N/A", - FingerprintDeviceData: &nvml.FingerprintDeviceData{ - DeviceData: &nvml.DeviceData{ - UUID: "1", - DeviceName: helper.StringToPtr("Type1"), - MemoryMiB: helper.Uint64ToPtr(256), - PowerW: helper.UintToPtr(2), - BAR1MiB: helper.Uint64ToPtr(256), + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), }, - PCIBusID: "pciBusID1", - PCIBandwidthMBPerS: nil, - CoresClockMHz: helper.UintToPtr(1), - MemoryClockMHz: helper.UintToPtr(1), - DisplayState: "Enabled", - PersistenceMode: "Enabled", - }, - ExpectedResult: map[string]string{ - MemoryMiBAttr: "256", - PowerWAttr: "2", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: notAvailable, - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", - }, - }, - { - Name: "CoresClockMHz is nil and has to be replaced to N/A", - FingerprintDeviceData: &nvml.FingerprintDeviceData{ - DeviceData: &nvml.DeviceData{ - UUID: "1", - DeviceName: helper.StringToPtr("Type1"), - MemoryMiB: helper.Uint64ToPtr(256), - PowerW: helper.UintToPtr(2), - BAR1MiB: helper.Uint64ToPtr(256), + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), }, - PCIBusID: "pciBusID1", - PCIBandwidthMBPerS: helper.UintToPtr(1), - CoresClockMHz: nil, - MemoryClockMHz: helper.UintToPtr(1), - DisplayState: "Enabled", - PersistenceMode: "Enabled", - }, - ExpectedResult: map[string]string{ - MemoryMiBAttr: "256", - PowerWAttr: "2", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: notAvailable, - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", - }, - }, - { - Name: "MemoryClockMHz is nil and has to be replaced to N/A", - FingerprintDeviceData: &nvml.FingerprintDeviceData{ - DeviceData: &nvml.DeviceData{ - UUID: "1", - DeviceName: helper.StringToPtr("Type1"), - MemoryMiB: helper.Uint64ToPtr(256), - PowerW: helper.UintToPtr(2), - BAR1MiB: helper.Uint64ToPtr(256), - }, - PCIBusID: "pciBusID1", - PCIBandwidthMBPerS: helper.UintToPtr(1), - CoresClockMHz: helper.UintToPtr(1), - MemoryClockMHz: nil, - DisplayState: "Enabled", - PersistenceMode: "Enabled", - }, - ExpectedResult: map[string]string{ - MemoryMiBAttr: "256", - PowerWAttr: "2", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: notAvailable, - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", }, }, } { t.Run(testCase.Name, func(t *testing.T) { actualResult := attributesFromFingerprintDeviceData(testCase.FingerprintDeviceData) - require.New(t).Equal(testCase.ExpectedResult, actualResult) + require.Equal(t, testCase.ExpectedResult, actualResult) }) } } @@ -570,7 +456,7 @@ func TestDeviceGroupFromFingerprintData(t *testing.T) { Name string GroupName string Devices []*nvml.FingerprintDeviceData - CommonAttributes map[string]string + CommonAttributes map[string]*structs.Attribute ExpectedResult *device.DeviceGroup }{ { @@ -628,15 +514,37 @@ func TestDeviceGroupFromFingerprintData(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "100", - PowerWAttr: "2", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(2), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, }, }, }, @@ -675,8 +583,10 @@ func TestDeviceGroupFromFingerprintData(t *testing.T) { PersistenceMode: "Enabled", }, }, - CommonAttributes: map[string]string{ - DriverVersionAttr: "1", + CommonAttributes: map[string]*structs.Attribute{ + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, ExpectedResult: &device.DeviceGroup{ Vendor: vendor, @@ -698,24 +608,50 @@ func TestDeviceGroupFromFingerprintData(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "100", - PowerWAttr: "2", - BAR1MiBAttr: "256", - DriverVersionAttr: "1", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(2), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, }, }, { Name: "Devices are not provided", GroupName: "Type1", - CommonAttributes: map[string]string{ - DriverVersionAttr: "1", + CommonAttributes: map[string]*structs.Attribute{ + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, Devices: nil, ExpectedResult: nil, @@ -806,16 +742,40 @@ func TestWriteFingerprintToChannel(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "10", - PowerWAttr: "100", - BAR1MiBAttr: "256", - DriverVersionAttr: "1", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(10), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, }, }, @@ -893,16 +853,40 @@ func TestWriteFingerprintToChannel(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "10", - DriverVersionAttr: "1", - PowerWAttr: "100", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(10), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, }, { @@ -918,16 +902,40 @@ func TestWriteFingerprintToChannel(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "11", - DriverVersionAttr: "1", - PowerWAttr: "100", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(11), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, }, { @@ -943,16 +951,40 @@ func TestWriteFingerprintToChannel(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "12", - DriverVersionAttr: "1", - PowerWAttr: "100", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(12), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, }, }, @@ -1030,16 +1062,40 @@ func TestWriteFingerprintToChannel(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "10", - DriverVersionAttr: "1", - PowerWAttr: "100", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(10), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, }, { @@ -1062,16 +1118,40 @@ func TestWriteFingerprintToChannel(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "11", - DriverVersionAttr: "1", - PowerWAttr: "100", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(11), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, }, }, @@ -1092,7 +1172,7 @@ func TestWriteFingerprintToChannel(t *testing.T) { sort.Slice(testCase.ExpectedWriteToChannel.Devices, func(i, j int) bool { return testCase.ExpectedWriteToChannel.Devices[i].Name < testCase.ExpectedWriteToChannel.Devices[j].Name }) - require.New(t).Equal(testCase.ExpectedWriteToChannel, actualResult) + require.Equal(t, testCase.ExpectedWriteToChannel, actualResult) }) } } @@ -1191,16 +1271,40 @@ func TestFingerprint(t *testing.T) { }, }, }, - Attributes: map[string]string{ - MemoryMiBAttr: "10", - DriverVersionAttr: "1", - PowerWAttr: "100", - BAR1MiBAttr: "256", - PCIBandwidthMBPerSAttr: "1", - CoresClockMHzAttr: "1", - MemoryClockMHzAttr: "1", - DisplayStateAttr: "Enabled", - PersistenceModeAttr: "Enabled", + Attributes: map[string]*structs.Attribute{ + MemoryAttr: { + Int: helper.Int64ToPtr(10), + Unit: structs.UnitMiB, + }, + PowerAttr: { + Int: helper.Int64ToPtr(100), + Unit: structs.UnitW, + }, + BAR1Attr: { + Int: helper.Int64ToPtr(256), + Unit: structs.UnitMiB, + }, + PCIBandwidthAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMBPerS, + }, + CoresClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + MemoryClockAttr: { + Int: helper.Int64ToPtr(1), + Unit: structs.UnitMHz, + }, + DisplayStateAttr: { + String: helper.StringToPtr("Enabled"), + }, + PersistenceModeAttr: { + String: helper.StringToPtr("Enabled"), + }, + DriverVersionAttr: { + String: helper.StringToPtr("1"), + }, }, }, }, diff --git a/plugins/device/device.go b/plugins/device/device.go index 82cdec650..11ceb9344 100644 --- a/plugins/device/device.go +++ b/plugins/device/device.go @@ -5,6 +5,7 @@ import ( "time" "github.com/hashicorp/nomad/plugins/base" + "github.com/hashicorp/nomad/plugins/shared/structs" ) const ( @@ -69,7 +70,7 @@ type DeviceGroup struct { Devices []*Device // Attributes are a set of attributes shared for all the devices. - Attributes map[string]string + Attributes map[string]*structs.Attribute } // Device is an instance of a particular device. diff --git a/plugins/device/plugin_test.go b/plugins/device/plugin_test.go index 638ae7439..6779e50f7 100644 --- a/plugins/device/plugin_test.go +++ b/plugins/device/plugin_test.go @@ -8,6 +8,9 @@ import ( pb "github.com/golang/protobuf/proto" plugin "github.com/hashicorp/go-plugin" + "github.com/hashicorp/nomad/helper" + psstructs "github.com/hashicorp/nomad/plugins/shared/structs" + "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/plugins/base" "github.com/hashicorp/nomad/plugins/shared/hclspec" @@ -179,6 +182,12 @@ func TestDevicePlugin_Fingerprint(t *testing.T) { Vendor: "nvidia", Type: DeviceTypeGPU, Name: "foo", + Attributes: map[string]*psstructs.Attribute{ + "memory": { + Int: helper.Int64ToPtr(4), + Unit: "GiB", + }, + }, }, } devices2 := []*DeviceGroup{ diff --git a/plugins/device/proto/device.pb.go b/plugins/device/proto/device.pb.go index b230fe12b..a5b6c28c8 100644 --- a/plugins/device/proto/device.pb.go +++ b/plugins/device/proto/device.pb.go @@ -7,6 +7,7 @@ import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" import timestamp "github.com/golang/protobuf/ptypes/timestamp" +import proto1 "github.com/hashicorp/nomad/plugins/shared/structs/proto" import ( context "golang.org/x/net/context" @@ -35,7 +36,7 @@ func (m *FingerprintRequest) Reset() { *m = FingerprintRequest{} } func (m *FingerprintRequest) String() string { return proto.CompactTextString(m) } func (*FingerprintRequest) ProtoMessage() {} func (*FingerprintRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{0} + return fileDescriptor_device_c5ad1463d0f8d225, []int{0} } func (m *FingerprintRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_FingerprintRequest.Unmarshal(m, b) @@ -70,7 +71,7 @@ func (m *FingerprintResponse) Reset() { *m = FingerprintResponse{} } func (m *FingerprintResponse) String() string { return proto.CompactTextString(m) } func (*FingerprintResponse) ProtoMessage() {} func (*FingerprintResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{1} + return fileDescriptor_device_c5ad1463d0f8d225, []int{1} } func (m *FingerprintResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_FingerprintResponse.Unmarshal(m, b) @@ -109,17 +110,17 @@ type DeviceGroup struct { Devices []*DetectedDevice `protobuf:"bytes,4,rep,name=devices,proto3" json:"devices,omitempty"` // attributes allows adding attributes to be used for constraints or // affinities. - Attributes map[string]string `protobuf:"bytes,5,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Attributes map[string]*proto1.Attribute `protobuf:"bytes,5,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *DeviceGroup) Reset() { *m = DeviceGroup{} } func (m *DeviceGroup) String() string { return proto.CompactTextString(m) } func (*DeviceGroup) ProtoMessage() {} func (*DeviceGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{2} + return fileDescriptor_device_c5ad1463d0f8d225, []int{2} } func (m *DeviceGroup) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DeviceGroup.Unmarshal(m, b) @@ -167,7 +168,7 @@ func (m *DeviceGroup) GetDevices() []*DetectedDevice { return nil } -func (m *DeviceGroup) GetAttributes() map[string]string { +func (m *DeviceGroup) GetAttributes() map[string]*proto1.Attribute { if m != nil { return m.Attributes } @@ -196,7 +197,7 @@ func (m *DetectedDevice) Reset() { *m = DetectedDevice{} } func (m *DetectedDevice) String() string { return proto.CompactTextString(m) } func (*DetectedDevice) ProtoMessage() {} func (*DetectedDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{3} + return fileDescriptor_device_c5ad1463d0f8d225, []int{3} } func (m *DetectedDevice) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DetectedDevice.Unmarshal(m, b) @@ -258,7 +259,7 @@ func (m *DeviceLocality) Reset() { *m = DeviceLocality{} } func (m *DeviceLocality) String() string { return proto.CompactTextString(m) } func (*DeviceLocality) ProtoMessage() {} func (*DeviceLocality) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{4} + return fileDescriptor_device_c5ad1463d0f8d225, []int{4} } func (m *DeviceLocality) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DeviceLocality.Unmarshal(m, b) @@ -299,7 +300,7 @@ func (m *ReserveRequest) Reset() { *m = ReserveRequest{} } func (m *ReserveRequest) String() string { return proto.CompactTextString(m) } func (*ReserveRequest) ProtoMessage() {} func (*ReserveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{5} + return fileDescriptor_device_c5ad1463d0f8d225, []int{5} } func (m *ReserveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReserveRequest.Unmarshal(m, b) @@ -342,7 +343,7 @@ func (m *ReserveResponse) Reset() { *m = ReserveResponse{} } func (m *ReserveResponse) String() string { return proto.CompactTextString(m) } func (*ReserveResponse) ProtoMessage() {} func (*ReserveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{6} + return fileDescriptor_device_c5ad1463d0f8d225, []int{6} } func (m *ReserveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReserveResponse.Unmarshal(m, b) @@ -387,7 +388,7 @@ func (m *ContainerReservation) Reset() { *m = ContainerReservation{} } func (m *ContainerReservation) String() string { return proto.CompactTextString(m) } func (*ContainerReservation) ProtoMessage() {} func (*ContainerReservation) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{7} + return fileDescriptor_device_c5ad1463d0f8d225, []int{7} } func (m *ContainerReservation) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ContainerReservation.Unmarshal(m, b) @@ -446,7 +447,7 @@ func (m *Mount) Reset() { *m = Mount{} } func (m *Mount) String() string { return proto.CompactTextString(m) } func (*Mount) ProtoMessage() {} func (*Mount) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{8} + return fileDescriptor_device_c5ad1463d0f8d225, []int{8} } func (m *Mount) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Mount.Unmarshal(m, b) @@ -507,7 +508,7 @@ func (m *DeviceSpec) Reset() { *m = DeviceSpec{} } func (m *DeviceSpec) String() string { return proto.CompactTextString(m) } func (*DeviceSpec) ProtoMessage() {} func (*DeviceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{9} + return fileDescriptor_device_c5ad1463d0f8d225, []int{9} } func (m *DeviceSpec) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DeviceSpec.Unmarshal(m, b) @@ -559,7 +560,7 @@ func (m *StatsRequest) Reset() { *m = StatsRequest{} } func (m *StatsRequest) String() string { return proto.CompactTextString(m) } func (*StatsRequest) ProtoMessage() {} func (*StatsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{10} + return fileDescriptor_device_c5ad1463d0f8d225, []int{10} } func (m *StatsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatsRequest.Unmarshal(m, b) @@ -592,7 +593,7 @@ func (m *StatsResponse) Reset() { *m = StatsResponse{} } func (m *StatsResponse) String() string { return proto.CompactTextString(m) } func (*StatsResponse) ProtoMessage() {} func (*StatsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{11} + return fileDescriptor_device_c5ad1463d0f8d225, []int{11} } func (m *StatsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatsResponse.Unmarshal(m, b) @@ -636,7 +637,7 @@ func (m *DeviceGroupStats) Reset() { *m = DeviceGroupStats{} } func (m *DeviceGroupStats) String() string { return proto.CompactTextString(m) } func (*DeviceGroupStats) ProtoMessage() {} func (*DeviceGroupStats) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{12} + return fileDescriptor_device_c5ad1463d0f8d225, []int{12} } func (m *DeviceGroupStats) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DeviceGroupStats.Unmarshal(m, b) @@ -702,7 +703,7 @@ func (m *DeviceStats) Reset() { *m = DeviceStats{} } func (m *DeviceStats) String() string { return proto.CompactTextString(m) } func (*DeviceStats) ProtoMessage() {} func (*DeviceStats) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{13} + return fileDescriptor_device_c5ad1463d0f8d225, []int{13} } func (m *DeviceStats) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DeviceStats.Unmarshal(m, b) @@ -759,7 +760,7 @@ func (m *StatObject) Reset() { *m = StatObject{} } func (m *StatObject) String() string { return proto.CompactTextString(m) } func (*StatObject) ProtoMessage() {} func (*StatObject) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{14} + return fileDescriptor_device_c5ad1463d0f8d225, []int{14} } func (m *StatObject) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatObject.Unmarshal(m, b) @@ -824,7 +825,7 @@ func (m *StatValue) Reset() { *m = StatValue{} } func (m *StatValue) String() string { return proto.CompactTextString(m) } func (*StatValue) ProtoMessage() {} func (*StatValue) Descriptor() ([]byte, []int) { - return fileDescriptor_device_ebefe60214c28313, []int{15} + return fileDescriptor_device_c5ad1463d0f8d225, []int{15} } func (m *StatValue) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatValue.Unmarshal(m, b) @@ -904,7 +905,7 @@ func init() { proto.RegisterType((*FingerprintRequest)(nil), "hashicorp.nomad.plugins.device.FingerprintRequest") proto.RegisterType((*FingerprintResponse)(nil), "hashicorp.nomad.plugins.device.FingerprintResponse") proto.RegisterType((*DeviceGroup)(nil), "hashicorp.nomad.plugins.device.DeviceGroup") - proto.RegisterMapType((map[string]string)(nil), "hashicorp.nomad.plugins.device.DeviceGroup.AttributesEntry") + proto.RegisterMapType((map[string]*proto1.Attribute)(nil), "hashicorp.nomad.plugins.device.DeviceGroup.AttributesEntry") proto.RegisterType((*DetectedDevice)(nil), "hashicorp.nomad.plugins.device.DetectedDevice") proto.RegisterType((*DeviceLocality)(nil), "hashicorp.nomad.plugins.device.DeviceLocality") proto.RegisterType((*ReserveRequest)(nil), "hashicorp.nomad.plugins.device.ReserveRequest") @@ -1134,77 +1135,80 @@ var _DevicePlugin_serviceDesc = grpc.ServiceDesc{ } func init() { - proto.RegisterFile("github.com/hashicorp/nomad/plugins/device/proto/device.proto", fileDescriptor_device_ebefe60214c28313) + proto.RegisterFile("github.com/hashicorp/nomad/plugins/device/proto/device.proto", fileDescriptor_device_c5ad1463d0f8d225) } -var fileDescriptor_device_ebefe60214c28313 = []byte{ - // 1086 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xeb, 0x8e, 0xdb, 0x44, - 0x14, 0x26, 0xf7, 0xe4, 0x64, 0x2f, 0xdd, 0xd9, 0x05, 0x85, 0x40, 0xe9, 0xca, 0x12, 0x52, 0x59, - 0xa8, 0x53, 0xa5, 0x08, 0xaa, 0x42, 0xa1, 0xed, 0xa6, 0xd0, 0x95, 0x60, 0xb7, 0x72, 0xab, 0x4a, - 0x2d, 0x12, 0xd6, 0xc4, 0x9e, 0xc6, 0xd3, 0xda, 0x33, 0xc6, 0x33, 0x4e, 0x15, 0xde, 0x80, 0x37, - 0xe1, 0x4f, 0x5f, 0x80, 0x77, 0x80, 0x87, 0xe0, 0x49, 0xd0, 0x5c, 0x9c, 0x38, 0xdb, 0xa5, 0x49, - 0xe0, 0x97, 0xe7, 0x5c, 0xbe, 0x6f, 0x8e, 0xcf, 0x39, 0x73, 0x66, 0xe0, 0xeb, 0x09, 0x95, 0x51, - 0x3e, 0x76, 0x03, 0x9e, 0x0c, 0x22, 0x2c, 0x22, 0x1a, 0xf0, 0x2c, 0x1d, 0x30, 0x9e, 0xe0, 0x70, - 0x90, 0xc6, 0xf9, 0x84, 0x32, 0x31, 0x08, 0xc9, 0x94, 0x06, 0x64, 0x90, 0x66, 0x5c, 0x72, 0x2b, - 0xb8, 0x5a, 0x40, 0x1f, 0xcd, 0x21, 0xae, 0x86, 0xb8, 0x16, 0xe2, 0x1a, 0xaf, 0xfe, 0x95, 0x09, - 0xe7, 0x93, 0xd8, 0x42, 0xc7, 0xf9, 0xf3, 0x81, 0xa4, 0x09, 0x11, 0x12, 0x27, 0xa9, 0x21, 0x70, - 0x0e, 0x00, 0x7d, 0x47, 0xd9, 0x84, 0x64, 0x69, 0x46, 0x99, 0xf4, 0xc8, 0x2f, 0x39, 0x11, 0xd2, - 0x21, 0xb0, 0xbf, 0xa4, 0x15, 0x29, 0x67, 0x82, 0xa0, 0x53, 0xd8, 0x32, 0xbc, 0xfe, 0x24, 0xe3, - 0x79, 0xda, 0xab, 0x1c, 0xd6, 0xae, 0x76, 0x87, 0x9f, 0xba, 0x6f, 0x0f, 0xc2, 0x1d, 0xe9, 0xcf, - 0xf7, 0x0a, 0xe2, 0x75, 0xc3, 0x85, 0xe0, 0xfc, 0x59, 0x85, 0x6e, 0xc9, 0x88, 0xde, 0x83, 0xe6, - 0x94, 0xb0, 0x90, 0x67, 0xbd, 0xca, 0x61, 0xe5, 0x6a, 0xc7, 0xb3, 0x12, 0xba, 0x02, 0x16, 0xe6, - 0xcb, 0x59, 0x4a, 0x7a, 0x55, 0x6d, 0x04, 0xa3, 0x7a, 0x3c, 0x4b, 0x49, 0xc9, 0x81, 0xe1, 0x84, - 0xf4, 0x6a, 0x65, 0x87, 0x53, 0x9c, 0x10, 0xf4, 0x00, 0x5a, 0x46, 0x12, 0xbd, 0xba, 0x0e, 0xda, - 0x5d, 0x1d, 0xb4, 0x24, 0x81, 0x24, 0xa1, 0x89, 0xcf, 0x2b, 0xe0, 0xe8, 0x27, 0x00, 0x2c, 0x65, - 0x46, 0xc7, 0xb9, 0x24, 0xa2, 0xd7, 0xd0, 0x64, 0x5f, 0x6d, 0x90, 0x01, 0xf7, 0xee, 0x1c, 0x7d, - 0x9f, 0xc9, 0x6c, 0xe6, 0x95, 0xe8, 0xfa, 0xb7, 0x61, 0xf7, 0x9c, 0x19, 0x5d, 0x82, 0xda, 0x4b, - 0x32, 0xb3, 0x09, 0x51, 0x4b, 0x74, 0x00, 0x8d, 0x29, 0x8e, 0xf3, 0x22, 0x0f, 0x46, 0xb8, 0x55, - 0xbd, 0x59, 0x71, 0xfe, 0xa8, 0xc0, 0xce, 0x72, 0xdc, 0x68, 0x07, 0xaa, 0x27, 0x23, 0x8b, 0xae, - 0x9e, 0x8c, 0x50, 0x0f, 0x5a, 0x11, 0xc1, 0xb1, 0x8c, 0x66, 0x1a, 0xde, 0xf6, 0x0a, 0x11, 0x5d, - 0x03, 0x64, 0x96, 0x7e, 0x48, 0x44, 0x90, 0xd1, 0x54, 0x52, 0xce, 0x6c, 0x2a, 0xf7, 0x8c, 0x65, - 0xb4, 0x30, 0xa0, 0x33, 0xe8, 0x46, 0xaf, 0xfc, 0x98, 0x07, 0x38, 0xa6, 0x72, 0xd6, 0xab, 0x1f, - 0x56, 0xd6, 0xcb, 0xaa, 0xfa, 0xfc, 0x60, 0x51, 0x1e, 0x44, 0xaf, 0x8a, 0xb5, 0xe3, 0xaa, 0xd8, - 0xcb, 0x56, 0xf4, 0x21, 0x40, 0x1a, 0x50, 0x7f, 0x9c, 0x0b, 0x9f, 0x86, 0xf6, 0x1f, 0xda, 0x69, - 0x40, 0xef, 0xe5, 0xe2, 0x24, 0x74, 0x06, 0xb0, 0xe3, 0x11, 0x41, 0xb2, 0x29, 0xb1, 0x5d, 0x8b, - 0x2e, 0x83, 0x2d, 0xb9, 0x4f, 0x43, 0xa1, 0x9b, 0xb3, 0xe3, 0x75, 0x8c, 0xe6, 0x24, 0x14, 0x4e, - 0x0c, 0xbb, 0x73, 0x80, 0x6d, 0xe8, 0xa7, 0xb0, 0x1d, 0x70, 0x26, 0x31, 0x65, 0x24, 0xf3, 0x33, - 0x22, 0xf4, 0x26, 0xdd, 0xe1, 0xe7, 0xab, 0x7e, 0xe3, 0xb8, 0x00, 0x19, 0x42, 0xac, 0x32, 0xe2, - 0x6d, 0x05, 0x25, 0xad, 0xf3, 0x7b, 0x15, 0x0e, 0x2e, 0x72, 0x43, 0x1e, 0xd4, 0x09, 0x9b, 0x0a, - 0x7b, 0x78, 0xbe, 0xf9, 0x2f, 0x5b, 0xb9, 0xf7, 0xd9, 0xd4, 0x76, 0x8f, 0xe6, 0x42, 0xb7, 0xa1, - 0x99, 0xf0, 0x9c, 0x49, 0xd1, 0xab, 0x6a, 0xd6, 0x8f, 0x57, 0xb1, 0xfe, 0xa8, 0xbc, 0x3d, 0x0b, - 0x42, 0xa3, 0xc5, 0xe9, 0xa8, 0x69, 0xfc, 0xd1, 0x7a, 0x75, 0x7c, 0x94, 0x92, 0x60, 0x7e, 0x32, - 0xfa, 0x5f, 0x42, 0x67, 0x1e, 0xd7, 0x46, 0x6d, 0xfb, 0x33, 0x34, 0x74, 0x3c, 0xe8, 0x03, 0xe8, - 0x48, 0x2c, 0x5e, 0xfa, 0x29, 0x96, 0x51, 0x51, 0x6f, 0xa5, 0x78, 0x88, 0x65, 0xa4, 0x8c, 0x11, - 0x17, 0xd2, 0x18, 0x0d, 0x47, 0x5b, 0x29, 0x0a, 0x63, 0x46, 0x70, 0xe8, 0x73, 0x16, 0xcf, 0x74, - 0xcf, 0xb6, 0xbd, 0xb6, 0x52, 0x9c, 0xb1, 0x78, 0xe6, 0x44, 0x00, 0x8b, 0x78, 0xff, 0xc7, 0x26, - 0x87, 0xd0, 0x4d, 0x49, 0x96, 0x50, 0x21, 0x28, 0x67, 0xc2, 0x1e, 0x8d, 0xb2, 0xca, 0xd9, 0x81, - 0xad, 0x47, 0x12, 0x4b, 0x51, 0xcc, 0xd1, 0xa7, 0xb0, 0x6d, 0x65, 0xdb, 0x70, 0x0f, 0xa0, 0xa9, - 0x47, 0x67, 0x51, 0xfe, 0xeb, 0x1b, 0x4c, 0x0e, 0xc3, 0x64, 0xf1, 0xce, 0xeb, 0x2a, 0x5c, 0x3a, - 0x6f, 0xfc, 0xd7, 0x01, 0x8a, 0xa0, 0x5e, 0x9a, 0x9c, 0x7a, 0xad, 0x74, 0xa5, 0x61, 0xa9, 0xd7, - 0xe8, 0x05, 0xec, 0x50, 0x26, 0x24, 0x66, 0x01, 0xf1, 0x85, 0x62, 0xb4, 0xd3, 0xf2, 0x78, 0xd3, - 0x30, 0xdd, 0x13, 0x4b, 0xa3, 0x25, 0xd3, 0xaa, 0xdb, 0xb4, 0xac, 0xeb, 0x27, 0x80, 0xde, 0x74, - 0xba, 0xa0, 0x6f, 0xee, 0x96, 0xfb, 0x66, 0xed, 0xdb, 0xc6, 0x24, 0xab, 0xd4, 0x64, 0x7f, 0x55, - 0x8a, 0xbb, 0xc6, 0xa4, 0xea, 0x18, 0x5a, 0x22, 0x4f, 0x12, 0x9c, 0xcd, 0xec, 0xa1, 0xff, 0x64, - 0x15, 0xb1, 0xc2, 0x3d, 0x51, 0x7c, 0x5e, 0x81, 0x44, 0x77, 0xa0, 0x61, 0xd2, 0x64, 0x62, 0x3b, - 0x5a, 0x87, 0xe2, 0x6c, 0xfc, 0x82, 0x04, 0xd2, 0x33, 0x40, 0x74, 0x13, 0x3a, 0xf3, 0x2b, 0x59, - 0x97, 0xa2, 0x3b, 0xec, 0xbb, 0xe6, 0xd2, 0x76, 0x8b, 0x4b, 0xdb, 0x7d, 0x5c, 0x78, 0x78, 0x0b, - 0x67, 0xe7, 0xb7, 0x1a, 0xc0, 0x82, 0x0f, 0x9d, 0x42, 0x93, 0x11, 0x21, 0x49, 0x68, 0x3b, 0xeb, - 0x8b, 0xf5, 0x63, 0x71, 0x4f, 0x35, 0xd0, 0x54, 0xc9, 0xb2, 0xa0, 0x67, 0x4b, 0xf7, 0x9c, 0x19, - 0x2b, 0xb7, 0x36, 0xe0, 0x7c, 0xdb, 0x35, 0x47, 0xa0, 0x5b, 0xda, 0xf2, 0x82, 0x9a, 0xdf, 0x59, - 0xae, 0xf9, 0x46, 0x79, 0x9d, 0x97, 0xbc, 0x1f, 0xad, 0x73, 0x9b, 0x7e, 0xbb, 0xbc, 0xd5, 0x06, - 0x5d, 0x50, 0x6a, 0xae, 0xd7, 0x55, 0xe8, 0xcc, 0x0d, 0xc8, 0x85, 0xfd, 0xe7, 0x31, 0xc7, 0xd2, - 0x67, 0x79, 0x42, 0x32, 0x2c, 0x79, 0xe6, 0x4f, 0x71, 0xac, 0x37, 0xad, 0x78, 0x7b, 0xda, 0x74, - 0x5a, 0x58, 0x9e, 0xe0, 0x18, 0x0d, 0xe1, 0x5d, 0xe3, 0x1f, 0x12, 0xc6, 0x13, 0xca, 0xe6, 0x88, - 0xaa, 0x46, 0x18, 0xb2, 0xd1, 0xc2, 0xa6, 0x30, 0x47, 0xb0, 0x47, 0xd9, 0xf9, 0x1d, 0x54, 0xff, - 0xd4, 0xbc, 0x5d, 0xca, 0x96, 0xf9, 0x5d, 0xd8, 0x57, 0xbe, 0xe7, 0xd9, 0xeb, 0xda, 0x5b, 0xd1, - 0x9c, 0xe3, 0xbe, 0x0c, 0x20, 0x64, 0x46, 0xd9, 0x44, 0xbb, 0x35, 0x74, 0xae, 0x3a, 0x46, 0xa3, - 0xcc, 0xef, 0x43, 0x7b, 0xcc, 0x79, 0xac, 0x8d, 0x4d, 0xf3, 0x86, 0x50, 0xb2, 0x32, 0x21, 0xa8, - 0xe7, 0x8c, 0xca, 0x5e, 0xcb, 0xcc, 0x14, 0xb5, 0x56, 0x3a, 0xf5, 0xa0, 0xe8, 0xb5, 0x8d, 0x4e, - 0xad, 0x87, 0x7f, 0x57, 0x61, 0xcb, 0x1c, 0xc6, 0x87, 0x3a, 0xbb, 0xe8, 0x57, 0xe8, 0x96, 0x1e, - 0x9c, 0x68, 0xb8, 0xaa, 0x0a, 0x6f, 0xbe, 0x59, 0xfb, 0x37, 0x36, 0xc2, 0x98, 0x79, 0xec, 0xbc, - 0x73, 0xbd, 0x82, 0x62, 0x68, 0xd9, 0x77, 0x01, 0x5a, 0xf9, 0x7e, 0x59, 0x7e, 0x71, 0xf4, 0x07, - 0x6b, 0xfb, 0x17, 0xfb, 0xa1, 0x08, 0x1a, 0x66, 0x00, 0x7d, 0xb6, 0x4e, 0xa7, 0x15, 0x37, 0x49, - 0xff, 0xda, 0x9a, 0xde, 0x8b, 0xff, 0xba, 0xd7, 0x7a, 0xd6, 0x30, 0x13, 0xa4, 0xa9, 0x3f, 0x37, - 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x5c, 0x8f, 0xd7, 0x6b, 0x0c, 0x00, 0x00, +var fileDescriptor_device_c5ad1463d0f8d225 = []byte{ + // 1129 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xef, 0x8e, 0xdb, 0x44, + 0x10, 0x27, 0xff, 0x93, 0xc9, 0xf5, 0xda, 0xdb, 0x3b, 0x50, 0x08, 0x94, 0x9e, 0x2c, 0x21, 0x95, + 0x83, 0x3a, 0x25, 0x45, 0x50, 0x95, 0x7f, 0x6d, 0x2f, 0xe5, 0x7a, 0x12, 0xdc, 0x55, 0x6e, 0x55, + 0xa9, 0x45, 0xc2, 0xda, 0xd8, 0xdb, 0x78, 0x5b, 0x7b, 0xd7, 0x78, 0xd7, 0xa9, 0xc2, 0x27, 0xbe, + 0xf2, 0x26, 0x7c, 0xe9, 0x0b, 0xf0, 0x10, 0x3c, 0x04, 0x4f, 0x82, 0xf6, 0x8f, 0x13, 0xe7, 0x7a, + 0x6d, 0x12, 0xf8, 0xe4, 0xdd, 0x99, 0xf9, 0xfd, 0x66, 0x3c, 0x3b, 0x3b, 0x3b, 0xf0, 0xcd, 0x84, + 0xca, 0x28, 0x1f, 0xbb, 0x01, 0x4f, 0x06, 0x11, 0x16, 0x11, 0x0d, 0x78, 0x96, 0x0e, 0x18, 0x4f, + 0x70, 0x38, 0x48, 0xe3, 0x7c, 0x42, 0x99, 0x18, 0x84, 0x64, 0x4a, 0x03, 0x32, 0x48, 0x33, 0x2e, + 0xb9, 0xdd, 0xb8, 0x7a, 0x83, 0x3e, 0x9a, 0x43, 0x5c, 0x0d, 0x71, 0x2d, 0xc4, 0x35, 0x56, 0xfd, + 0x2b, 0x13, 0xce, 0x27, 0xb1, 0x85, 0x8e, 0xf3, 0x67, 0x03, 0x49, 0x13, 0x22, 0x24, 0x4e, 0x52, + 0x43, 0xd0, 0x3f, 0x5a, 0xc3, 0xbd, 0x88, 0x70, 0x46, 0xc2, 0x81, 0x90, 0x59, 0x1e, 0x48, 0x61, + 0xc3, 0xc0, 0x52, 0x66, 0x74, 0x9c, 0x4b, 0x1b, 0x89, 0xb3, 0x07, 0xe8, 0x07, 0xca, 0x26, 0x24, + 0x4b, 0x33, 0xca, 0xa4, 0x47, 0x7e, 0xcd, 0x89, 0x90, 0x0e, 0x81, 0xdd, 0x25, 0xa9, 0x48, 0x39, + 0x13, 0x04, 0x9d, 0xc0, 0x96, 0x09, 0xd0, 0x9f, 0x64, 0x3c, 0x4f, 0x7b, 0x95, 0xfd, 0xda, 0xd5, + 0xee, 0xf0, 0x53, 0xf7, 0xed, 0x7f, 0xe3, 0x8e, 0xf4, 0xe7, 0x48, 0x41, 0xbc, 0x6e, 0xb8, 0xd8, + 0x38, 0xbf, 0xd7, 0xa0, 0x5b, 0x52, 0xa2, 0xf7, 0xa0, 0x39, 0x25, 0x2c, 0xe4, 0x59, 0xaf, 0xb2, + 0x5f, 0xb9, 0xda, 0xf1, 0xec, 0x0e, 0x5d, 0x01, 0x0b, 0xf3, 0xe5, 0x2c, 0x25, 0xbd, 0xaa, 0x56, + 0x82, 0x11, 0x3d, 0x9a, 0xa5, 0xa4, 0x64, 0xc0, 0x70, 0x42, 0x7a, 0xb5, 0xb2, 0xc1, 0x09, 0x4e, + 0x08, 0xba, 0x0f, 0x2d, 0xb3, 0x13, 0xbd, 0xba, 0x0e, 0xda, 0x5d, 0x1d, 0xb4, 0x24, 0x81, 0x24, + 0xa1, 0x89, 0xcf, 0x2b, 0xe0, 0xe8, 0x67, 0x80, 0x79, 0x0e, 0x45, 0xaf, 0xa1, 0xc9, 0xbe, 0xde, + 0x20, 0x03, 0xee, 0x9d, 0x39, 0xfa, 0x1e, 0x93, 0xd9, 0xcc, 0x2b, 0xd1, 0xf5, 0x53, 0xb8, 0x78, + 0x46, 0x8d, 0x2e, 0x41, 0xed, 0x05, 0x99, 0xd9, 0x84, 0xa8, 0x25, 0x3a, 0x82, 0xc6, 0x14, 0xc7, + 0xb9, 0xc9, 0x43, 0x77, 0xf8, 0xf9, 0x1b, 0x9d, 0x9b, 0x02, 0x70, 0x6d, 0x01, 0x2c, 0x1c, 0x7b, + 0x06, 0x7f, 0xab, 0x7a, 0xb3, 0xe2, 0xfc, 0x55, 0x81, 0xed, 0xe5, 0x5f, 0x45, 0xdb, 0x50, 0x3d, + 0x1e, 0x59, 0x87, 0xd5, 0xe3, 0x11, 0xea, 0x41, 0x2b, 0x22, 0x38, 0x96, 0xd1, 0x4c, 0x7b, 0x6c, + 0x7b, 0xc5, 0x16, 0x5d, 0x03, 0x64, 0x96, 0x7e, 0x48, 0x44, 0x90, 0xd1, 0x54, 0x52, 0xce, 0x6c, + 0xf6, 0x77, 0x8c, 0x66, 0xb4, 0x50, 0xa0, 0x53, 0xe8, 0x46, 0x2f, 0xfd, 0x98, 0x07, 0x38, 0xa6, + 0x72, 0xd6, 0xab, 0xeb, 0xf0, 0xdd, 0xf5, 0x72, 0xf7, 0xa3, 0x45, 0x79, 0x10, 0xbd, 0x2c, 0xd6, + 0x8e, 0xab, 0x62, 0x2f, 0x6b, 0xd1, 0x87, 0x00, 0x69, 0x40, 0xfd, 0x71, 0x2e, 0x7c, 0x1a, 0xda, + 0x7f, 0x68, 0xa7, 0x01, 0xbd, 0x9b, 0x8b, 0xe3, 0xd0, 0x19, 0xc0, 0xb6, 0x47, 0x04, 0xc9, 0xa6, + 0xc4, 0x16, 0x3a, 0xba, 0x0c, 0xb6, 0x4a, 0x7c, 0x1a, 0x0a, 0x5d, 0xcf, 0x1d, 0xaf, 0x63, 0x24, + 0xc7, 0xa1, 0x70, 0x62, 0xb8, 0x38, 0x07, 0xd8, 0x3b, 0xf0, 0x04, 0x2e, 0x04, 0x9c, 0x49, 0x4c, + 0x19, 0xc9, 0xfc, 0x8c, 0x08, 0xed, 0xa4, 0x3b, 0xfc, 0x62, 0xd5, 0x6f, 0x1c, 0x16, 0x20, 0x43, + 0x88, 0x55, 0x46, 0xbc, 0xad, 0xa0, 0x24, 0x75, 0xfe, 0xac, 0xc2, 0xde, 0x79, 0x66, 0xc8, 0x83, + 0x3a, 0x61, 0x53, 0x61, 0xef, 0xdb, 0x77, 0xff, 0xc5, 0x95, 0x7b, 0x8f, 0x4d, 0x6d, 0xc1, 0x69, + 0x2e, 0xf4, 0x2d, 0x34, 0x13, 0x9e, 0x33, 0x29, 0x7a, 0x55, 0xcd, 0xfa, 0xf1, 0x2a, 0xd6, 0x9f, + 0x94, 0xb5, 0x67, 0x41, 0x68, 0xb4, 0xb8, 0x50, 0x35, 0x8d, 0x3f, 0x58, 0xef, 0x1c, 0x1f, 0xa6, + 0x24, 0x98, 0x5f, 0xa6, 0xfe, 0x57, 0xd0, 0x99, 0xc7, 0x75, 0x4e, 0xa5, 0xef, 0x95, 0x2b, 0xbd, + 0x53, 0x2e, 0xdb, 0x5f, 0xa0, 0xa1, 0xe3, 0x41, 0x1f, 0x40, 0x47, 0x62, 0xf1, 0xc2, 0x4f, 0xb1, + 0x8c, 0x8a, 0xf3, 0x56, 0x82, 0x07, 0x58, 0x46, 0x4a, 0x19, 0x71, 0x21, 0x8d, 0xd2, 0x70, 0xb4, + 0x95, 0xa0, 0x50, 0x66, 0x04, 0x87, 0x3e, 0x67, 0xf1, 0x4c, 0xd7, 0x6c, 0xdb, 0x6b, 0x2b, 0xc1, + 0x29, 0x8b, 0x67, 0x4e, 0x04, 0xb0, 0x88, 0xf7, 0x7f, 0x38, 0xd9, 0x87, 0x6e, 0x4a, 0xb2, 0x84, + 0x0a, 0x41, 0x39, 0x13, 0xf6, 0x6a, 0x94, 0x45, 0xce, 0x36, 0x6c, 0x3d, 0x94, 0x58, 0x8a, 0xa2, + 0xf5, 0x3e, 0x81, 0x0b, 0x76, 0x6f, 0x0b, 0xee, 0x3e, 0x34, 0x75, 0xb7, 0x2d, 0x8e, 0xff, 0xfa, + 0x06, 0xcd, 0xc6, 0x30, 0x59, 0xbc, 0xf3, 0xaa, 0x0a, 0x97, 0xce, 0x2a, 0xdf, 0xd8, 0x73, 0x11, + 0xd4, 0x4b, 0xcd, 0x56, 0xaf, 0x95, 0xac, 0xd4, 0x5f, 0xf5, 0x1a, 0x3d, 0x87, 0x6d, 0xca, 0x84, + 0xc4, 0x2c, 0x20, 0xbe, 0x50, 0x8c, 0xb6, 0xc1, 0x1e, 0x6e, 0x1a, 0xa6, 0x7b, 0x6c, 0x69, 0xf4, + 0xce, 0x94, 0xea, 0x05, 0x5a, 0x96, 0xf5, 0x13, 0x40, 0xaf, 0x1b, 0x9d, 0x53, 0x37, 0x77, 0x96, + 0x3b, 0xe4, 0x9a, 0x0f, 0x94, 0x49, 0x56, 0xa9, 0xc8, 0xfe, 0xae, 0x14, 0xcf, 0x93, 0x49, 0xd5, + 0x21, 0xb4, 0x44, 0x9e, 0x24, 0x38, 0x9b, 0xd9, 0x4b, 0xff, 0xc9, 0x2a, 0x62, 0x85, 0x7b, 0xac, + 0xf8, 0xbc, 0x02, 0x89, 0x6e, 0x43, 0xc3, 0xa4, 0xc9, 0xc4, 0x76, 0xb0, 0x0e, 0xc5, 0xe9, 0xf8, + 0x39, 0x09, 0xa4, 0x67, 0x80, 0xe8, 0x26, 0x74, 0xe6, 0xe3, 0x80, 0x3e, 0x8a, 0xee, 0xb0, 0xef, + 0x9a, 0x81, 0xc1, 0x2d, 0x06, 0x06, 0xf7, 0x51, 0x61, 0xe1, 0x2d, 0x8c, 0x9d, 0x3f, 0x6a, 0x00, + 0x0b, 0x3e, 0x74, 0x02, 0x4d, 0x46, 0x84, 0x24, 0xa1, 0xad, 0xac, 0x2f, 0xd7, 0x8f, 0xc5, 0x3d, + 0xd1, 0x40, 0x73, 0x4a, 0x96, 0x05, 0x3d, 0x5d, 0x7a, 0x1a, 0x4d, 0x5b, 0xb9, 0xb5, 0x01, 0xe7, + 0xdb, 0x5e, 0x46, 0x02, 0xdd, 0x92, 0xcb, 0x73, 0xce, 0xfc, 0xf6, 0xf2, 0x99, 0x6f, 0x94, 0xd7, + 0xf9, 0x91, 0xf7, 0xa3, 0x75, 0x1e, 0xe0, 0xef, 0x97, 0x5d, 0x6d, 0x50, 0x05, 0xa5, 0xe2, 0x7a, + 0x55, 0x85, 0xce, 0x5c, 0x81, 0x5c, 0xd8, 0x7d, 0x16, 0x73, 0x2c, 0x7d, 0x96, 0x27, 0x24, 0xc3, + 0x92, 0x67, 0xfe, 0x14, 0xc7, 0xda, 0x69, 0xc5, 0xdb, 0xd1, 0xaa, 0x93, 0x42, 0xf3, 0x18, 0xc7, + 0x68, 0x08, 0xef, 0x1a, 0xfb, 0x90, 0x30, 0x9e, 0x50, 0x36, 0x47, 0x54, 0x35, 0xc2, 0x90, 0x8d, + 0x16, 0x3a, 0x85, 0x39, 0x80, 0x1d, 0xca, 0xce, 0x7a, 0x50, 0xf5, 0x53, 0xf3, 0x2e, 0x52, 0xb6, + 0xcc, 0xef, 0xc2, 0xae, 0xb2, 0x3d, 0xcb, 0x5e, 0xd7, 0xd6, 0x8a, 0xe6, 0x0c, 0xf7, 0x65, 0x00, + 0x21, 0x33, 0xca, 0x26, 0xda, 0xac, 0xa1, 0x73, 0xd5, 0x31, 0x12, 0xa5, 0x7e, 0x1f, 0xda, 0x63, + 0xce, 0x63, 0xad, 0x6c, 0x9a, 0x19, 0x42, 0xed, 0x95, 0x0a, 0x41, 0x3d, 0x67, 0x54, 0xf6, 0x5a, + 0xa6, 0xa7, 0xa8, 0xb5, 0x92, 0xa9, 0x81, 0xa2, 0xd7, 0x36, 0x32, 0xb5, 0x1e, 0xfe, 0x53, 0x85, + 0x2d, 0x73, 0x19, 0x1f, 0xe8, 0xec, 0xa2, 0xdf, 0xa0, 0x5b, 0x9a, 0x51, 0xd1, 0x70, 0xd5, 0x29, + 0xbc, 0x3e, 0xe6, 0xf6, 0x6f, 0x6c, 0x84, 0x31, 0xfd, 0xd8, 0x79, 0xe7, 0x7a, 0x05, 0xc5, 0xd0, + 0xb2, 0x73, 0x01, 0x5a, 0x39, 0xbf, 0x2c, 0x4f, 0x1c, 0xfd, 0xc1, 0xda, 0xf6, 0x85, 0x3f, 0x14, + 0x41, 0xc3, 0x34, 0xa0, 0xcf, 0xd6, 0xa9, 0xb4, 0xe2, 0x25, 0xe9, 0x5f, 0x5b, 0xd3, 0x7a, 0xf1, + 0x5f, 0x77, 0x5b, 0x4f, 0x1b, 0xa6, 0x83, 0x34, 0xf5, 0xe7, 0xc6, 0xbf, 0x01, 0x00, 0x00, 0xff, + 0xff, 0xe1, 0x29, 0x35, 0x33, 0xe7, 0x0c, 0x00, 0x00, } diff --git a/plugins/device/proto/device.proto b/plugins/device/proto/device.proto index bcf27424d..09b2212bc 100644 --- a/plugins/device/proto/device.proto +++ b/plugins/device/proto/device.proto @@ -3,6 +3,7 @@ package hashicorp.nomad.plugins.device; option go_package = "proto"; import "google/protobuf/timestamp.proto"; +import "github.com/hashicorp/nomad/plugins/shared/structs/proto/attribute.proto"; // DevicePlugin is the API exposed by device plugins service DevicePlugin { @@ -48,7 +49,7 @@ message DeviceGroup { // attributes allows adding attributes to be used for constraints or // affinities. - map attributes = 5; + map attributes = 5; } // DetectedDevice is a single detected device. diff --git a/plugins/device/util.go b/plugins/device/util.go index d0a005970..1d694c3c8 100644 --- a/plugins/device/util.go +++ b/plugins/device/util.go @@ -1,7 +1,10 @@ package device -import "github.com/hashicorp/nomad/plugins/device/proto" -import "github.com/golang/protobuf/ptypes" +import ( + "github.com/golang/protobuf/ptypes" + "github.com/hashicorp/nomad/plugins/device/proto" + "github.com/hashicorp/nomad/plugins/shared/structs" +) // convertProtoDeviceGroups converts between a list of proto and structs DeviceGroup func convertProtoDeviceGroups(in []*proto.DeviceGroup) []*DeviceGroup { @@ -28,7 +31,7 @@ func convertProtoDeviceGroup(in *proto.DeviceGroup) *DeviceGroup { Type: in.DeviceType, Name: in.DeviceName, Devices: convertProtoDevices(in.Devices), - Attributes: in.Attributes, + Attributes: structs.ConvertProtoAttributeMap(in.Attributes), } } @@ -164,7 +167,7 @@ func convertStructDeviceGroup(in *DeviceGroup) *proto.DeviceGroup { DeviceType: in.Type, DeviceName: in.Name, Devices: convertStructDevices(in.Devices), - Attributes: in.Attributes, + Attributes: structs.ConvertStructAttributeMap(in.Attributes), } } diff --git a/plugins/shared/structs/proto/attribute.pb.go b/plugins/shared/structs/proto/attribute.pb.go index af3dd4d48..b0abdf024 100644 --- a/plugins/shared/structs/proto/attribute.pb.go +++ b/plugins/shared/structs/proto/attribute.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: attribute.proto +// source: github.com/hashicorp/nomad/plugins/shared/structs/proto/attribute.proto package proto @@ -38,7 +38,7 @@ func (m *Attribute) Reset() { *m = Attribute{} } func (m *Attribute) String() string { return proto.CompactTextString(m) } func (*Attribute) ProtoMessage() {} func (*Attribute) Descriptor() ([]byte, []int) { - return fileDescriptor_attribute_bfac9d16cf08e8f5, []int{0} + return fileDescriptor_attribute_5e512eadce7864ec, []int{0} } func (m *Attribute) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Attribute.Unmarshal(m, b) @@ -229,22 +229,25 @@ func init() { proto.RegisterType((*Attribute)(nil), "hashicorp.nomad.plugins.shared.structs.Attribute") } -func init() { proto.RegisterFile("attribute.proto", fileDescriptor_attribute_bfac9d16cf08e8f5) } - -var fileDescriptor_attribute_bfac9d16cf08e8f5 = []byte{ - // 209 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0xcf, 0xb1, 0x4e, 0xc3, 0x30, - 0x10, 0x06, 0xe0, 0x98, 0x36, 0x4d, 0x7c, 0x0b, 0x92, 0xa7, 0x22, 0x84, 0xb0, 0x18, 0x90, 0x27, - 0x2f, 0x3c, 0x01, 0x9d, 0x3c, 0x7b, 0x60, 0x60, 0x41, 0x97, 0x36, 0x34, 0x96, 0x8c, 0x1d, 0xd9, - 0xe7, 0x3e, 0x0f, 0x8f, 0x8a, 0xec, 0x88, 0xe9, 0x4e, 0xff, 0x77, 0xff, 0x70, 0x70, 0x8f, 0x44, - 0xc9, 0x4d, 0x85, 0x66, 0xbd, 0xa6, 0x48, 0x51, 0xbc, 0x2e, 0x98, 0x17, 0x77, 0x8e, 0x69, 0xd5, - 0x21, 0xfe, 0xe0, 0x45, 0xaf, 0xbe, 0x5c, 0x5d, 0xc8, 0x3a, 0x2f, 0x98, 0xe6, 0x8b, 0xce, 0x94, - 0xca, 0x99, 0xf2, 0xcb, 0x2f, 0x03, 0xfe, 0xfe, 0xdf, 0x15, 0x4f, 0xc0, 0xbf, 0x7d, 0x44, 0xfa, - 0xba, 0xa1, 0x3f, 0x32, 0xc9, 0x14, 0x33, 0x9d, 0x1d, 0x5b, 0xf4, 0x81, 0x5e, 0x3c, 0xc0, 0xe0, - 0xc2, 0x86, 0x77, 0x92, 0xa9, 0x9d, 0xe9, 0xec, 0xc1, 0x85, 0x46, 0xcf, 0x00, 0x99, 0x92, 0x0b, - 0xd7, 0xa6, 0x3b, 0xc9, 0x14, 0x37, 0x9d, 0xe5, 0x5b, 0x56, 0x0f, 0x1e, 0x61, 0x9c, 0x62, 0xf4, - 0x8d, 0xf7, 0x92, 0xa9, 0xd1, 0x74, 0x76, 0xa8, 0x49, 0x45, 0x01, 0xfb, 0x12, 0x1c, 0x1d, 0xfb, - 0xda, 0xb3, 0x6d, 0x3f, 0x0d, 0xd0, 0xdf, 0xd0, 0x97, 0xf9, 0x34, 0x7c, 0xf6, 0xed, 0xa7, 0xe9, - 0xd0, 0xc6, 0xdb, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x79, 0x18, 0x15, 0x15, 0xed, 0x00, 0x00, - 0x00, +func init() { + proto.RegisterFile("github.com/hashicorp/nomad/plugins/shared/structs/proto/attribute.proto", fileDescriptor_attribute_5e512eadce7864ec) +} + +var fileDescriptor_attribute_5e512eadce7864ec = []byte{ + // 229 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x8f, 0xb1, 0x4e, 0xc3, 0x30, + 0x10, 0x40, 0x63, 0xda, 0x34, 0xc9, 0x8d, 0x99, 0x8a, 0x10, 0x22, 0x62, 0x40, 0x99, 0xec, 0x81, + 0x2f, 0xa0, 0x0b, 0x99, 0x3d, 0x30, 0xb0, 0x20, 0x27, 0x0d, 0x89, 0x25, 0xd7, 0x17, 0xd9, 0xe7, + 0x7e, 0x0f, 0x9f, 0x8a, 0x72, 0x29, 0x4c, 0xf6, 0xbd, 0x77, 0x6f, 0x38, 0x78, 0x9f, 0x2c, 0xcd, + 0xa9, 0x97, 0x03, 0x5e, 0xd4, 0x6c, 0xe2, 0x6c, 0x07, 0x0c, 0x8b, 0xf2, 0x78, 0x31, 0x67, 0xb5, + 0xb8, 0x34, 0x59, 0x1f, 0x55, 0x9c, 0x4d, 0x18, 0xcf, 0x2a, 0x52, 0x48, 0x03, 0x45, 0xb5, 0x04, + 0x24, 0x54, 0x86, 0x28, 0xd8, 0x3e, 0xd1, 0x28, 0x79, 0xae, 0x5f, 0xfe, 0x6b, 0xc9, 0xb5, 0xbc, + 0xd5, 0x72, 0xab, 0xe5, 0xad, 0x7e, 0xfe, 0x11, 0x50, 0xbd, 0xfd, 0xb5, 0xf5, 0x23, 0x54, 0xdf, + 0x0e, 0x0d, 0x7d, 0x5d, 0x8d, 0x3b, 0x8a, 0x46, 0xb4, 0xa2, 0xcb, 0x74, 0xc9, 0xe8, 0xc3, 0xb8, + 0xfa, 0x1e, 0x0a, 0xeb, 0x37, 0x79, 0xd7, 0x88, 0x76, 0xd7, 0x65, 0xfa, 0x60, 0x3d, 0xab, 0x27, + 0x80, 0x48, 0xc1, 0xfa, 0x89, 0xed, 0xae, 0x11, 0x6d, 0xd5, 0x65, 0xba, 0xda, 0xd8, 0xba, 0xf0, + 0x00, 0x65, 0x8f, 0xe8, 0x58, 0xef, 0x1b, 0xd1, 0x96, 0x5d, 0xa6, 0x8b, 0x95, 0xac, 0xb2, 0x86, + 0x7d, 0xf2, 0x96, 0x8e, 0xf9, 0xda, 0x69, 0xfe, 0x9f, 0x0a, 0xc8, 0xaf, 0xc6, 0xa5, 0xf1, 0x54, + 0x7c, 0xe6, 0x7c, 0x53, 0x7f, 0xe0, 0xe7, 0xf5, 0x37, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x2e, 0x1a, + 0x5b, 0x25, 0x01, 0x00, 0x00, } diff --git a/plugins/shared/structs/units.go b/plugins/shared/structs/units.go index 5d418cb11..597be99c6 100644 --- a/plugins/shared/structs/units.go +++ b/plugins/shared/structs/units.go @@ -2,6 +2,53 @@ package structs import "sort" +const ( + // Binary SI Byte Units + UnitKiB = "KiB" + UnitMiB = "MiB" + UnitGiB = "GiB" + UnitTiB = "TiB" + UnitPiB = "PiB" + UnitEiB = "EiB" + + // Decimal SI Byte Units + UnitkB = "kB" + UnitKB = "KB" + UnitMB = "MB" + UnitGB = "GB" + UnitTB = "TB" + UnitPB = "PB" + UnitEB = "EB" + + // Binary SI Byte Rates + UnitKiBPerS = "KiB/s" + UnitMiBPerS = "MiB/s" + UnitGiBPerS = "GiB/s" + UnitTiBPerS = "TiB/s" + UnitPiBPerS = "PiB/s" + UnitEiBPerS = "EiB/s" + + // Decimal SI Byte Rates + UnitkBPerS = "kB/s" + UnitKBPerS = "KB/s" + UnitMBPerS = "MB/s" + UnitGBPerS = "GB/s" + UnitTBPerS = "TB/s" + UnitPBPerS = "PB/s" + UnitEBPerS = "EB/s" + + // Hertz units + UnitMHz = "MHz" + UnitGHz = "GHz" + + // Watts units + UnitmW = "mW" + UnitW = "W" + UnitkW = "kW" + UnitMW = "MW" + UnitGW = "GW" +) + var ( // numUnits is the number of known units numUnits = len(binarySIBytes) + len(decimalSIBytes) + len(binarySIByteRates) + len(decimalSIByteRates) + len(watts) + len(hertz) @@ -15,32 +62,32 @@ var ( binarySIBytes = []*Unit{ { - Name: "KiB", + Name: UnitKiB, Base: UnitByte, Multiplier: 1 << 10, }, { - Name: "MiB", + Name: UnitMiB, Base: UnitByte, Multiplier: 1 << 20, }, { - Name: "GiB", + Name: UnitGiB, Base: UnitByte, Multiplier: 1 << 30, }, { - Name: "TiB", + Name: UnitTiB, Base: UnitByte, Multiplier: 1 << 40, }, { - Name: "PiB", + Name: UnitPiB, Base: UnitByte, Multiplier: 1 << 50, }, { - Name: "EiB", + Name: UnitEiB, Base: UnitByte, Multiplier: 1 << 60, }, @@ -48,37 +95,37 @@ var ( decimalSIBytes = []*Unit{ { - Name: "kB", + Name: UnitkB, Base: UnitByte, Multiplier: Pow(1000, 1), }, { - Name: "KB", // Alternative name for kB + Name: UnitKB, // Alternative name for kB Base: UnitByte, Multiplier: Pow(1000, 1), }, { - Name: "MB", + Name: UnitMB, Base: UnitByte, Multiplier: Pow(1000, 2), }, { - Name: "GB", + Name: UnitGB, Base: UnitByte, Multiplier: Pow(1000, 3), }, { - Name: "TB", + Name: UnitTB, Base: UnitByte, Multiplier: Pow(1000, 4), }, { - Name: "PB", + Name: UnitPB, Base: UnitByte, Multiplier: Pow(1000, 5), }, { - Name: "EB", + Name: UnitEB, Base: UnitByte, Multiplier: Pow(1000, 6), }, @@ -86,32 +133,32 @@ var ( binarySIByteRates = []*Unit{ { - Name: "KiB/s", + Name: UnitKiBPerS, Base: UnitByteRate, Multiplier: 1 << 10, }, { - Name: "MiB/s", + Name: UnitMiBPerS, Base: UnitByteRate, Multiplier: 1 << 20, }, { - Name: "GiB/s", + Name: UnitGiBPerS, Base: UnitByteRate, Multiplier: 1 << 30, }, { - Name: "TiB/s", + Name: UnitTiBPerS, Base: UnitByteRate, Multiplier: 1 << 40, }, { - Name: "PiB/s", + Name: UnitPiBPerS, Base: UnitByteRate, Multiplier: 1 << 50, }, { - Name: "EiB/s", + Name: UnitEiBPerS, Base: UnitByteRate, Multiplier: 1 << 60, }, @@ -119,37 +166,37 @@ var ( decimalSIByteRates = []*Unit{ { - Name: "kB/s", + Name: UnitkBPerS, Base: UnitByteRate, Multiplier: Pow(1000, 1), }, { - Name: "KB/s", // Alternative name for kB/s + Name: UnitKBPerS, Base: UnitByteRate, Multiplier: Pow(1000, 1), }, { - Name: "MB/s", + Name: UnitMBPerS, Base: UnitByteRate, Multiplier: Pow(1000, 2), }, { - Name: "GB/s", + Name: UnitGBPerS, Base: UnitByteRate, Multiplier: Pow(1000, 3), }, { - Name: "TB/s", + Name: UnitTBPerS, Base: UnitByteRate, Multiplier: Pow(1000, 4), }, { - Name: "PB/s", + Name: UnitPBPerS, Base: UnitByteRate, Multiplier: Pow(1000, 5), }, { - Name: "EB/s", + Name: UnitEBPerS, Base: UnitByteRate, Multiplier: Pow(1000, 6), }, @@ -157,12 +204,12 @@ var ( hertz = []*Unit{ { - Name: "MHz", + Name: UnitMHz, Base: UnitHertz, Multiplier: Pow(1000, 1), }, { - Name: "GHz", + Name: UnitGHz, Base: UnitHertz, Multiplier: Pow(1000, 3), }, @@ -170,28 +217,28 @@ var ( watts = []*Unit{ { - Name: "mW", + Name: UnitmW, Base: UnitWatt, Multiplier: Pow(10, 3), InverseMultiplier: true, }, { - Name: "W", + Name: UnitW, Base: UnitWatt, Multiplier: 1, }, { - Name: "kW", + Name: UnitkW, Base: UnitWatt, Multiplier: Pow(10, 3), }, { - Name: "MW", + Name: UnitMW, Base: UnitWatt, Multiplier: Pow(10, 6), }, { - Name: "GW", + Name: UnitGW, Base: UnitWatt, Multiplier: Pow(10, 9), }, diff --git a/plugins/shared/structs/util.go b/plugins/shared/structs/util.go index dec6b9ad0..5f84fc4ad 100644 --- a/plugins/shared/structs/util.go +++ b/plugins/shared/structs/util.go @@ -25,6 +25,58 @@ func ConvertProtoAttribute(in *proto.Attribute) *Attribute { return out } +func ConvertProtoAttributeMap(in map[string]*proto.Attribute) map[string]*Attribute { + if in == nil { + return nil + } + + out := make(map[string]*Attribute, len(in)) + for k, a := range in { + out[k] = ConvertProtoAttribute(a) + } + + return out +} + +func ConvertStructsAttribute(in *Attribute) *proto.Attribute { + out := &proto.Attribute{ + Unit: in.Unit, + } + + if in.Int != nil { + out.Value = &proto.Attribute_IntVal{ + IntVal: *in.Int, + } + } else if in.Float != nil { + out.Value = &proto.Attribute_FloatVal{ + FloatVal: *in.Float, + } + } else if in.String != nil { + out.Value = &proto.Attribute_StringVal{ + StringVal: *in.String, + } + } else if in.Bool != nil { + out.Value = &proto.Attribute_BoolVal{ + BoolVal: *in.Bool, + } + } + + return out +} + +func ConvertStructAttributeMap(in map[string]*Attribute) map[string]*proto.Attribute { + if in == nil { + return nil + } + + out := make(map[string]*proto.Attribute, len(in)) + for k, a := range in { + out[k] = ConvertStructsAttribute(a) + } + + return out +} + func Pow(a, b int64) int64 { var p int64 = 1 for b > 0 {