diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index e4fddd1..0000000 --- a/.github/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Close inactive issues -on: - schedule: - - cron: "30 1 * * *" - -jobs: - close-issues: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: actions/stale@v8 - with: - days-before-issue-stale: -1 - days-before-issue-close: 30 - close-issue-message: "Closed due to inactivity." - days-before-pr-stale: -1 - days-before-pr-close: -1 - repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 04905a4..8feaaff 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ set -x # Stop display manager systemctl stop display-manager # systemctl --user -M YOUR_USERNAME@ stop plasma* - + # Unbind VTconsoles: might not be needed echo 0 > /sys/class/vtconsole/vtcon0/bind echo 0 > /sys/class/vtconsole/vtcon1/bind diff --git a/libvirt_hooks_setup.sh b/libvirt_hooks_setup.sh new file mode 100755 index 0000000..b1fff78 --- /dev/null +++ b/libvirt_hooks_setup.sh @@ -0,0 +1,151 @@ +#!/bin/sh + +INIT_SYSTEM="runit" # systemd, openrc, runit +GPU="nvidia" # nvidia, amd +DISPLAY_MANAGER="yes" # yes, no +WINDOW_MANAGER="niri" # required if not using display manager +START_WINDOW_MANAGER="dbus-run-session niri --session" # not sure if this works +GPU_PCI="pci_0000_01_00_0" +GPU_AUDIO_PCI="pci_0000_01_00_1" +VM_NAME="win10" # name of VM set during creation + +mkdir -pv tmp + +sudo_cmd="sudo" +if command -v doas >/dev/null; then + sudo_cmd="doas" +fi + +start_service() { + case $INIT_SYSTEM in + "systemd") echo "systemctl start $1";; + "openrc") echo "rc-service $1 start";; + "runit") echo "sv up $1";; + esac +} + +stop_service() { + case $INIT_SYSTEM in + "systemd") echo "systemctl stop $1";; + "openrc") echo "openrc $1 stop";; + "runit") echo "sv down $1";; + esac +} + +cat > ./tmp/qemu_hook<< "EOF" +#!/bin/bash + +GUEST_NAME="$1" +HOOK_NAME="$2" +STATE_NAME="$3" +MISC="${@:4}" + +BASEDIR="$(dirname $0)" + +HOOKPATH="$BASEDIR/qemu.d/$GUEST_NAME/$HOOK_NAME/$STATE_NAME" +set -e # If a script exits with an error, we should as well. + +if [ -f "$HOOKPATH" ]; then +eval \""$HOOKPATH"\" "$@" +elif [ -d "$HOOKPATH" ]; then +while read file; do + eval \""$file"\" "$@" +done <<< "$(find -L "$HOOKPATH" -maxdepth 1 -type f -executable -print;)" +fi +EOF + +if [ "$DISPLAY_MANAGER" = "yes" ]; then + # TODO: use service provided by package if display-manager is not valid service + dm_start=$(start_service "display-manager") + dm_stop=$(stop_service "display-manager") + + if [ "$INIT_SYSTEM" = "systemd" ]; then + plasma_stop="systemctl --user -M $USER@ stop plasma" + fi +else + dm_stop="pkill -x $WINDOW_MANAGER" + dm_start="su -l $USER -c $START_WINDOW_MANAGER" +fi + +if [ "$GPU" = "amd" ]; then + gpu_modules="amdgpu" +elif [ "$GPU" = "nvidia" ]; then + gpu_modules="nvidia_drm nvidia_modeset nvidia_uvm nvidia" +fi + +cat > ./tmp/libvirt_hook_start.sh<< EOF +#!/bin/bash +set -x + +$dm_stop +$plasma_stop + +# Unbind VTconsoles +echo 0 > /sys/class/vtconsole/vtcon0/bind +echo 0 > /sys/class/vtconsole/vtcon1/bind + +# Unbind EFI Framebuffer +echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind + +modprobe -r $gpu_modules + +virsh nodedev-detach $GPU_PCI +virsh nodedev-detach $GPU_AUDIO_PCI + +modprobe vfio-pci +EOF + +cat > ./tmp/libvirt_hook_stop.sh<< EOF +#!/bin/bash +set -x + +# Attach GPU devices to host +virsh nodedev-reattach $GPU_PCI +virsh nodedev-reattach $GPU_AUDIO_PCI + +# Unload vfio module +modprobe -r vfio-pci + +# Rebind framebuffer to host +echo "efi-framebuffer.0" > /sys/bus/platform/drivers/efi-framebuffer/bind + +# Load NVIDIA kernel modules +$(for module in $gpu_modules; do + echo "modprobe $module" +done) + +# Bind VTconsoles +echo 1 > /sys/class/vtconsole/vtcon0/bind +echo 1 > /sys/class/vtconsole/vtcon1/bind + +$dm_start +EOF + +get_yes_no_input() { + while true; do + echo -n "$1 (yes/no): " + read yn + case $yn in + [Yy]* ) return 0;; + [Nn]* ) return 1;; + * ) echo "Please answer yes or no.";; + esac + done +} + +chmod +x -v tmp/qemu_hook +chmod +x -v tmp/libvirt_hook_start.sh +chmod +x -v tmp/libvirt_hook_stop.sh + +if get_yes_no_input "Want me to copy hooks files?"; then + $sudo_cmd mkdir -pv /etc/libvirt/hooks + $sudo_cmd mkdir -pv /etc/libvirt/hooks/qemu.d/$VM_NAME/prepare/begin + $sudo_cmd mkdir -pv /etc/libvirt/hooks/qemu.d/$VM_NAME/release/end + + $sudo_cmd cp -v --preserve ./tmp/qemu_hook /etc/libvirt/hooks/qemu + $sudo_cmd cp -v --preserve ./tmp/libvirt_hook_start.sh /etc/libvirt/hooks/qemu.d/$VM_NAME/prepare/begin/start.sh + $sudo_cmd cp -v --preserve ./tmp/libvirt_hook_stop.sh /etc/libvirt/hooks/qemu.d/$VM_NAME/release/end/stop.sh + echo "\033[1;32m✓ DONE \033[0m" +else + echo "\033[1;32m✓ You can manually copy hooks from tmp directory.\033[0m" +fi