From 30adcf08cefa857c480359b5a67716dc2745302a Mon Sep 17 00:00:00 2001 From: Nydragon Date: Sat, 18 Jan 2025 22:04:46 +0100 Subject: [PATCH] feat: declarative module for libvirt hotplugging --- hosts/marr/default.nix | 10 +++-- hosts/marr/home.nix | 2 +- options/services/default.nix | 1 + options/services/udev/default.nix | 67 +++++++++++++++++++++++++++++++ options/services/udev/hotplug.sh | 42 +++++++++++++++++++ options/system/roles/desktop.nix | 1 + 6 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 options/services/udev/default.nix create mode 100644 options/services/udev/hotplug.sh diff --git a/hosts/marr/default.nix b/hosts/marr/default.nix index 4ebd685..892a5ba 100644 --- a/hosts/marr/default.nix +++ b/hosts/marr/default.nix @@ -40,6 +40,12 @@ enable = true; tags = [ "client" ]; }; + udev = { + enable = true; + libvirtHotplug."archlinux" = [ + "303a/1001/*" # Espressif JTG debug unit + ]; + }; }; }; @@ -180,9 +186,7 @@ brightnessctl pop-icon-theme - bottles - wine64 - ghidra + kicad-small ]; system.stateVersion = "24.11"; diff --git a/hosts/marr/home.nix b/hosts/marr/home.nix index 549d428..61cf0ce 100644 --- a/hosts/marr/home.nix +++ b/hosts/marr/home.nix @@ -13,7 +13,7 @@ home-manager.users.${username} = { imports = [ - ../../home/themes/catppuccin.nix + ../../home/themes/vanilla.nix ../../home ]; diff --git a/options/services/default.nix b/options/services/default.nix index 807556c..14a70f3 100644 --- a/options/services/default.nix +++ b/options/services/default.nix @@ -4,5 +4,6 @@ ./tailscale.nix ./rsync-backup ./cliphist.nix + ./udev ]; } diff --git a/options/services/udev/default.nix b/options/services/udev/default.nix new file mode 100644 index 0000000..978ed14 --- /dev/null +++ b/options/services/udev/default.nix @@ -0,0 +1,67 @@ +{ + lib, + config, + pkgs, + ... +}: +let + inherit (lib) + mkIf + mkEnableOption + mkOption + concatMapStrings + attrsToList + ; + inherit (lib.types) + str + attrsOf + listOf + ; + inherit (lib.my) getExe; + + cfg = config.modules.services.udev; + + bindUsb = pkgs.writers.writeBashBin "mount-usb" { + makeWrapperArgs = [ + "--prefix" + "PATH" + ":" + "${lib.makeBinPath [ pkgs.libvirt ]}" + ]; + } ./hotplug.sh; + + mkUdevHotplug = domain: product: '' + ENV{PRODUCT}=="${product}", \ + SUBSYSTEMS=="usb", \ + RUN+="${getExe bindUsb} ${domain}" + ''; +in +{ + + options.modules.services.udev = { + enable = mkEnableOption ""; + libvirtHotplug = mkOption { + default = [ ]; + type = attrsOf (listOf str); + description = '' + The udev rules used to match USB devices, all normal udev patterns are usable. + ''; + example = ''[ "303a/1001/*" ]''; + }; + }; + + config = mkIf cfg.enable { + services.udev = { + enable = true; + packages = [ + (pkgs.writeTextFile { + name = "udev-vm-hotplug-rules"; + text = concatMapStrings ( + { name, value }: concatMapStrings (product: mkUdevHotplug name product) value + ) (attrsToList cfg.libvirtHotplug); + destination = "/etc/udev/rules.d/99-hotplug.rules"; + }) + ]; + }; + }; +} diff --git a/options/services/udev/hotplug.sh b/options/services/udev/hotplug.sh new file mode 100644 index 0000000..b88a9fd --- /dev/null +++ b/options/services/udev/hotplug.sh @@ -0,0 +1,42 @@ +# Refer to https://github.com/olavmrk/usb-libvirt-hotplug/blob/master/usb-libvirt-hotplug.sh + +set -e +exec > >(systemd-cat -t "$0") 2>&1 + +PROG="$(basename "$0")" +DOMAIN="$1" + +if [ -z "${DOMAIN}" ]; then + echo "Missing libvirt domain parameter for $PROG." >&2 + exit 1 +fi + +if [ "$ACTION" == 'add' ]; then + COMMAND='attach-device' +elif [ "$ACTION" == 'remove' ]; then + COMMAND='detach-device' +else + echo "Invalid udev ACTION: $ACTION" >&2 + exit 1 +fi + +if [ -z "$BUSNUM" ]; then + echo "Missing udev BUSNUM environment variable." >&2 + exit 1 +fi + +if [ -z "$DEVNUM" ]; then + echo "Missing udev DEVNUM environment variable." >&2 + exit 1 +fi + +BUSNUM=$((10#$BUSNUM)) +DEVNUM=$((10#$DEVNUM)) + +virsh -c qemu:///system $COMMAND archlinux --live --file /dev/stdin < + +
+ + +END diff --git a/options/system/roles/desktop.nix b/options/system/roles/desktop.nix index d4b3c30..cc33981 100644 --- a/options/system/roles/desktop.nix +++ b/options/system/roles/desktop.nix @@ -50,6 +50,7 @@ in environment.systemPackages = [ cfg.terminal cfg.filemanager + pkgs.zotero ]; }; }