Syndicated actor for publishing Linux device events
src | ||
.gitignore | ||
build-nim-sbom.nix | ||
default.nix | ||
lock.json | ||
README.md | ||
sbom.json | ||
syndev.nimble | ||
Tupfile | ||
Tuprules.jq | ||
Tuprules.tup | ||
uevents.prs |
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 }>>