feat: declarative module for libvirt hotplugging
This commit is contained in:
parent
84bb8ad29e
commit
30adcf08ce
6 changed files with 119 additions and 4 deletions
|
@ -40,6 +40,12 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
tags = [ "client" ];
|
tags = [ "client" ];
|
||||||
};
|
};
|
||||||
|
udev = {
|
||||||
|
enable = true;
|
||||||
|
libvirtHotplug."archlinux" = [
|
||||||
|
"303a/1001/*" # Espressif JTG debug unit
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,9 +186,7 @@
|
||||||
brightnessctl
|
brightnessctl
|
||||||
pop-icon-theme
|
pop-icon-theme
|
||||||
|
|
||||||
bottles
|
kicad-small
|
||||||
wine64
|
|
||||||
ghidra
|
|
||||||
];
|
];
|
||||||
|
|
||||||
system.stateVersion = "24.11";
|
system.stateVersion = "24.11";
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
home-manager.users.${username} = {
|
home-manager.users.${username} = {
|
||||||
imports = [
|
imports = [
|
||||||
../../home/themes/catppuccin.nix
|
../../home/themes/vanilla.nix
|
||||||
../../home
|
../../home
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
./tailscale.nix
|
./tailscale.nix
|
||||||
./rsync-backup
|
./rsync-backup
|
||||||
./cliphist.nix
|
./cliphist.nix
|
||||||
|
./udev
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
67
options/services/udev/default.nix
Normal file
67
options/services/udev/default.nix
Normal file
|
@ -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";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
42
options/services/udev/hotplug.sh
Normal file
42
options/services/udev/hotplug.sh
Normal file
|
@ -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
|
||||||
|
<hostdev mode="subsystem" type="usb">
|
||||||
|
<source>
|
||||||
|
<address bus="$BUSNUM" device="$DEVNUM"/>
|
||||||
|
</source>
|
||||||
|
</hostdev>
|
||||||
|
END
|
|
@ -50,6 +50,7 @@ in
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
cfg.terminal
|
cfg.terminal
|
||||||
cfg.filemanager
|
cfg.filemanager
|
||||||
|
pkgs.zotero
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue