Syndicated actor for publishing Linux device events
Find a file
2024-08-07 09:58:22 +01:00
src Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00
.gitignore Build system refactor 2024-03-15 10:02:24 +00:00
build-nim-sbom.nix Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00
default.nix Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00
lock.json Build system refactor 2024-03-15 10:02:24 +00:00
README.md Convert udev notes to Nix 2024-08-07 09:58:22 +01:00
sbom.json Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00
syndev.nimble Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00
Tupfile Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00
Tuprules.jq Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00
Tuprules.tup Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00
uevents.prs Update to recent Syndicate Nim API 2024-08-06 18:23:46 +01:00

Synit device managment toolkit

Intended as a kit for building native a device manager for Synit. This is not a replacement for udev/eudev or mdev/mdevd.

Message Schema is at uevents.prs.

If you are looking for documentation on how to parse and handle Linux uevents, please let me know when you find it.

Example configuration for logging uevents:

#!/usr/bin/env -S syndicate-server --config

<q <service uevent-dump>>
? <a <service uevent-dump> <accepted ?stream>> [
  $stream ?? ?msg [
    $log ! <log "uevent" { line: ?msg }>
  ]
]

? <q <service uevent-dump>> [
  <require-service <daemon dump-uevent>>
  ? <service-object <daemon dump-uevent> ?obj> [
    let ?rewriter = <* $config [<rewrite ?resp <a <service uevent-dump> $resp>>]>
    $obj <resolve <uevent-dump> $rewriter>
  ]
]

<daemon dump-uevent {
    argv:  ["/bin/dump-uevent" ]
    clearEnv: #t
    env: { BUILD_SUM: $sum }
    protocol: application/syndicate
  }>

Example message stream:

<uevent "power_supply" "/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:18/PNP0C09:01/PNP0C0A:03/power_supply/BAT0" change {POWER_SUPPLY_CAPACITY: 98, POWER_SUPPLY_CAPACITY_LEVEL: "Normal", POWER_SUPPLY_CYCLE_COUNT: 236, POWER_SUPPLY_ENERGY_FULL: 44672000, POWER_SUPPLY_ENERGY_FULL_DESIGN: 50464000, POWER_SUPPLY_ENERGY_NOW: 43821000, POWER_SUPPLY_MANUFACTURER: "ASUSTeK", POWER_SUPPLY_MODEL_NAME: "ASUS Battery", POWER_SUPPLY_NAME: "BAT0", POWER_SUPPLY_POWER_NOW: 7691000, POWER_SUPPLY_PRESENT: 1, POWER_SUPPLY_SERIAL_NUMBER: " ", POWER_SUPPLY_STATUS: "Charging", POWER_SUPPLY_TECHNOLOGY: "Li-ion", POWER_SUPPLY_TYPE: "Battery", POWER_SUPPLY_VOLTAGE_MIN_DESIGN: 15200000, POWER_SUPPLY_VOLTAGE_NOW: 15200000} 3916>
,uevent "hidraw" "/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2/0003:248A:5B2F.0011/hidraw/hidraw2" add {DEVNAME: "hidraw2", MAJOR: 247, MINOR: 2} 3980>
<uevent "hid" "/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2/0003:248A:5B2F.0011" bind {DRIVER: "hid-generic", HID_ID: "0003:0000248A:00005B2F", HID_NAME: "XCTECH Ninjutso Katana Superlight", HID_PHYS: "usb-0000:00:14.0-2/input2", HID_UNIQ: 0, MODALIAS: "hid:b0003g0001v0000248Ap00005B2F"} 3981>
<uevent "usb" "/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2" bind {DEVTYPE: "usb_interface", DRIVER: "usbhid", INTERFACE: "3/0/0", MODALIAS: "usb:v248Ap5B2Fd0116dc00dsc00dp00ic03isc00ip00in02", PRODUCT: "248a/5b2f/116", TYPE: "0/0/0"} 3982>

Assertions from udev

If you want assertions of devices instead of messages and you are running udev then let udev do the work for you.

As a NixOS module:

{ pkgs, ... }:

{
  services.udev.extraRules =
    let
      script = pkgs.writeShellScript "udev-syndicate-rule.sh" ''
        if [ -z "$DEVNAME" -o -z "$MAJOR" -o -z "$MINOR" ]
        then
                exit
        fi

        HARDWARE_DIR=/run/etc/syndicate/hardware
        PR_FILE=$HARDWARE_DIR/$MAJOR-$MINOR.pr

        mkdir -p $HARDWARE_DIR

        case "$ACTION" in
                remove)
                        rm -f $PR_FILE
                        ;;
                *)
                        echo '<device ' > $PR_FILE
                        udevadm info --json=short $DEVNAME >> $PR_FILE
                        echo '>' >> $PR_FILE
                        ;;
        esac
      '';
    in
    ''
      ACTION=="add|change|move|remove", RUN+="${script}"
    '';
}

Load the files generated by the script into a dataspace:

let ?devices = dataspace
<require-service <config-watcher "/run/etc/syndicate/hardware" { config: $devices }>>