From afc5ca2d1ca61e8d9f32fd5f345efd48dcf45f60 Mon Sep 17 00:00:00 2001 From: Brian McGee Date: Wed, 8 Jan 2025 14:02:09 +0000 Subject: [PATCH] feat: use linux input Bus enum with udev data I'm not sure why I created a separate Bus enum for udev. From the source, as best I can tell, it's using https://github.com/systemd/systemd/blob/8e3347f3bd3d9a01b8f39b0858eab74084ecf20a/src/basic/linux/input.h#L252-L275. This aligns with that and should fix #166. Signed-off-by: Brian McGee --- pkg/hwinfo/input.go | 23 ++++- pkg/linux/input/input.go | 18 +--- pkg/linux/input/input_test.go | 2 +- pkg/udev/udev.go | 27 +----- pkg/udev/udev_bus.go | 160 ---------------------------------- 5 files changed, 25 insertions(+), 205 deletions(-) delete mode 100644 pkg/udev/udev_bus.go diff --git a/pkg/hwinfo/input.go b/pkg/hwinfo/input.go index ed8b485..56bdb3a 100644 --- a/pkg/hwinfo/input.go +++ b/pkg/hwinfo/input.go @@ -1,7 +1,11 @@ package hwinfo import ( + "errors" "fmt" + "log/slog" + + "github.com/numtide/nixos-facter/pkg/udev" "github.com/numtide/nixos-facter/pkg/linux/input" ) @@ -10,7 +14,7 @@ import ( // error. // It accepts a deviceIdx to ensure it continues on from the last device index generated by hwinfo. func captureTouchpads(deviceIdx uint) ([]HardwareDevice, error) { - inputDevices, err := input.ReadDevices(nil, true) + inputDevices, err := input.ReadDevices(nil) if err != nil { return nil, fmt.Errorf("failed to read input devices: %w", err) } @@ -18,7 +22,18 @@ func captureTouchpads(deviceIdx uint) ([]HardwareDevice, error) { var result []HardwareDevice //nolint:prealloc for _, inputDevice := range inputDevices { - if !inputDevice.Udev.Input.IsTouchpad { + + path := "/sys" + inputDevice.Sysfs + + udevData, err := udev.Read(path) + if errors.Is(err, udev.ErrNotFound) { + slog.Warn("udev data not found", "name", inputDevice.Name, "sysfs", inputDevice.Sysfs) + continue + } else if err != nil { + return nil, fmt.Errorf("failed to fetch udev data for device %q with udev data: %w", path, err) + } + + if !udevData.Input.IsTouchpad { // currently, we are only interested in touchpads, as hwinfo does not capture them // eventually, we may take over more of the input processing that hwinfo performs continue @@ -35,11 +50,11 @@ func captureTouchpads(deviceIdx uint) ([]HardwareDevice, error) { Class: HardwareClassMouse, BaseClass: NewBaseClassID(BaseClassTouchpad), Vendor: &ID{ - Name: inputDevice.Udev.Vendor, + Name: udevData.Vendor, Value: inputDevice.Vendor, }, Device: &ID{ - Name: inputDevice.Udev.Model, + Name: udevData.Model, Value: inputDevice.Product, }, SysfsID: inputDevice.Sysfs, diff --git a/pkg/linux/input/input.go b/pkg/linux/input/input.go index 7169da6..a7fe434 100644 --- a/pkg/linux/input/input.go +++ b/pkg/linux/input/input.go @@ -2,16 +2,12 @@ package input import ( "bufio" - "errors" "fmt" "io" - "log/slog" "os" "regexp" "strconv" "strings" - - "github.com/numtide/nixos-facter/pkg/udev" ) //go:generate enumer -type=Bus -json -text -trimprefix Bus -output=./input_bus.go @@ -74,7 +70,6 @@ type Device struct { Sysfs string Phys string Capabilities map[string]string - Udev *udev.Udev } func (d *Device) Path() string { @@ -101,7 +96,7 @@ func (d *Device) EventHandler() string { return "" } -func ReadDevices(r io.ReadCloser, udevAnnotate bool) ([]*Device, error) { +func ReadDevices(r io.ReadCloser) ([]*Device, error) { var err error if r == nil { @@ -123,17 +118,6 @@ func ReadDevices(r io.ReadCloser, udevAnnotate bool) ([]*Device, error) { line := scanner.Text() if line == "" { - // try to append udev data - if udevAnnotate { - device.Udev, err = udev.Read("/sys" + device.Sysfs) - - if errors.Is(err, udev.ErrNotFound) { - slog.Warn("udev data not found", "name", device.Name, "sysfs", device.Sysfs) - } else if err != nil { - return nil, fmt.Errorf("failed to annotate with udev data: %w", err) - } - } - devices = append(devices, device) device = nil diff --git a/pkg/linux/input/input_test.go b/pkg/linux/input/input_test.go index 9f2df6f..617ca31 100644 --- a/pkg/linux/input/input_test.go +++ b/pkg/linux/input/input_test.go @@ -56,7 +56,7 @@ func TestReadDevices(t *testing.T) { as := require.New(t) r := io.NopCloser(bytes.NewReader([]byte(devices))) - devices, err := input.ReadDevices(r, false) + devices, err := input.ReadDevices(r) as.NoError(err) expected := []*input.Device{ diff --git a/pkg/udev/udev.go b/pkg/udev/udev.go index 1b31bab..72d2055 100644 --- a/pkg/udev/udev.go +++ b/pkg/udev/udev.go @@ -51,27 +51,8 @@ import ( "fmt" "strconv" "unsafe" -) - -//go:generate enumer -type=Bus -json -text -transform=snake -trimprefix Bus -output=./udev_bus.go -type Bus int //nolint:recvcheck -const ( - BusAta Bus = iota // ATA (IDE) devices - BusBluetooth - BusI8042 - BusI2c // Inter-Integrated Circuit - BusIeee1394 // Firewire - BusPci - BusPciExpress - BusPcmcia // Personal Computer Memory Card International Association - BusPlatform // Devices on a system's motherboard - BusScsi - BusSerial - BusSerio // Serial interface controller devices - BusSpi // Serial Peripheral Interface connected devices - BusUsb - BusVirtio + "github.com/numtide/nixos-facter/pkg/linux/input" ) //go:generate enumer -type=Type -json -text -trimprefix Type -output=./udev_type.go @@ -210,7 +191,7 @@ func NewUdevPci(env map[string]string) (*Pci, error) { } type Udev struct { - Bus Bus + Bus input.Bus Type Type Model string ModelID uint16 @@ -270,11 +251,11 @@ func NewUdev(env map[string]string) (*Udev, error) { var err error switch result.Bus { - case BusUsb: + case input.BusUsb: if result.Usb, err = NewUdevUsb(env); err != nil { return nil, fmt.Errorf("failed to parse usb: %w", err) } - case BusPci: + case input.BusPci: if result.Pci, err = NewUdevPci(env); err != nil { return nil, fmt.Errorf("failed to parse pci: %w", err) } diff --git a/pkg/udev/udev_bus.go b/pkg/udev/udev_bus.go deleted file mode 100644 index 6906953..0000000 --- a/pkg/udev/udev_bus.go +++ /dev/null @@ -1,160 +0,0 @@ -// Code generated by "enumer -type=Bus -json -text -transform=snake -trimprefix Bus -output=./udev_bus.go"; DO NOT EDIT. - -package udev - -import ( - "encoding/json" - "fmt" - "strings" -) - -const _BusName = "atabluetoothi8042i2cieee1394pcipci_expresspcmciaplatformscsiserialseriospiusbvirtio" - -var _BusIndex = [...]uint8{0, 3, 12, 17, 20, 28, 31, 42, 48, 56, 60, 66, 71, 74, 77, 83} - -const _BusLowerName = "atabluetoothi8042i2cieee1394pcipci_expresspcmciaplatformscsiserialseriospiusbvirtio" - -func (i Bus) String() string { - if i < 0 || i >= Bus(len(_BusIndex)-1) { - return fmt.Sprintf("Bus(%d)", i) - } - return _BusName[_BusIndex[i]:_BusIndex[i+1]] -} - -// An "invalid array index" compiler error signifies that the constant values have changed. -// Re-run the stringer command to generate them again. -func _BusNoOp() { - var x [1]struct{} - _ = x[BusAta-(0)] - _ = x[BusBluetooth-(1)] - _ = x[BusI8042-(2)] - _ = x[BusI2c-(3)] - _ = x[BusIeee1394-(4)] - _ = x[BusPci-(5)] - _ = x[BusPciExpress-(6)] - _ = x[BusPcmcia-(7)] - _ = x[BusPlatform-(8)] - _ = x[BusScsi-(9)] - _ = x[BusSerial-(10)] - _ = x[BusSerio-(11)] - _ = x[BusSpi-(12)] - _ = x[BusUsb-(13)] - _ = x[BusVirtio-(14)] -} - -var _BusValues = []Bus{BusAta, BusBluetooth, BusI8042, BusI2c, BusIeee1394, BusPci, BusPciExpress, BusPcmcia, BusPlatform, BusScsi, BusSerial, BusSerio, BusSpi, BusUsb, BusVirtio} - -var _BusNameToValueMap = map[string]Bus{ - _BusName[0:3]: BusAta, - _BusLowerName[0:3]: BusAta, - _BusName[3:12]: BusBluetooth, - _BusLowerName[3:12]: BusBluetooth, - _BusName[12:17]: BusI8042, - _BusLowerName[12:17]: BusI8042, - _BusName[17:20]: BusI2c, - _BusLowerName[17:20]: BusI2c, - _BusName[20:28]: BusIeee1394, - _BusLowerName[20:28]: BusIeee1394, - _BusName[28:31]: BusPci, - _BusLowerName[28:31]: BusPci, - _BusName[31:42]: BusPciExpress, - _BusLowerName[31:42]: BusPciExpress, - _BusName[42:48]: BusPcmcia, - _BusLowerName[42:48]: BusPcmcia, - _BusName[48:56]: BusPlatform, - _BusLowerName[48:56]: BusPlatform, - _BusName[56:60]: BusScsi, - _BusLowerName[56:60]: BusScsi, - _BusName[60:66]: BusSerial, - _BusLowerName[60:66]: BusSerial, - _BusName[66:71]: BusSerio, - _BusLowerName[66:71]: BusSerio, - _BusName[71:74]: BusSpi, - _BusLowerName[71:74]: BusSpi, - _BusName[74:77]: BusUsb, - _BusLowerName[74:77]: BusUsb, - _BusName[77:83]: BusVirtio, - _BusLowerName[77:83]: BusVirtio, -} - -var _BusNames = []string{ - _BusName[0:3], - _BusName[3:12], - _BusName[12:17], - _BusName[17:20], - _BusName[20:28], - _BusName[28:31], - _BusName[31:42], - _BusName[42:48], - _BusName[48:56], - _BusName[56:60], - _BusName[60:66], - _BusName[66:71], - _BusName[71:74], - _BusName[74:77], - _BusName[77:83], -} - -// BusString retrieves an enum value from the enum constants string name. -// Throws an error if the param is not part of the enum. -func BusString(s string) (Bus, error) { - if val, ok := _BusNameToValueMap[s]; ok { - return val, nil - } - - if val, ok := _BusNameToValueMap[strings.ToLower(s)]; ok { - return val, nil - } - return 0, fmt.Errorf("%s does not belong to Bus values", s) -} - -// BusValues returns all values of the enum -func BusValues() []Bus { - return _BusValues -} - -// BusStrings returns a slice of all String values of the enum -func BusStrings() []string { - strs := make([]string, len(_BusNames)) - copy(strs, _BusNames) - return strs -} - -// IsABus returns "true" if the value is listed in the enum definition. "false" otherwise -func (i Bus) IsABus() bool { - for _, v := range _BusValues { - if i == v { - return true - } - } - return false -} - -// MarshalJSON implements the json.Marshaler interface for Bus -func (i Bus) MarshalJSON() ([]byte, error) { - return json.Marshal(i.String()) -} - -// UnmarshalJSON implements the json.Unmarshaler interface for Bus -func (i *Bus) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return fmt.Errorf("Bus should be a string, got %s", data) - } - - var err error - *i, err = BusString(s) - return err -} - -// MarshalText implements the encoding.TextMarshaler interface for Bus -func (i Bus) MarshalText() ([]byte, error) { - return []byte(i.String()), nil -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface for Bus -func (i *Bus) UnmarshalText(text []byte) error { - var err error - *i, err = BusString(string(text)) - return err -}