dot

vizie's NixOS desktop: Hyprland, CachyOS kernel and gaming tweaks

60 lines2702 bytesBourne Again Shell (bash)executable
1#!/usr/bin/env bash
2# Build and boot the desktop configuration in a QEMU VM (see modules/nixos/vm.nix).
3#
4# ./vm.sh build and start the VM
5# ./vm.sh --fresh the same, but start from an empty VM disk
6#
7# The VM renders on the host GPU through virgl. QEMU's own window can't get a GL
8# context on the NVIDIA driver, so it renders headless on a Mesa GPU (the
9# Ryzen's integrated Radeon here) and is shown over VNC on this machine only:
10# vncviewer localhost:5905 (e.g. nix run nixpkgs#tigervnc -- localhost:5905)
11#
12# The VM's disk is desktop.qcow2 in this directory (git ignores it). A QEMU
13# monitor socket, vm-monitor.sock, takes screenshots and key presses from
14# scripts, e.g.: echo 'screendump shot.ppm' | socat - UNIX-CONNECT:vm-monitor.sock
15# The VM's console (boot messages, then a login prompt) goes to vm-serial.log.
16#
17# SSH: ssh -p 2222 vizie@localhost, with the key in $VM_SSH_KEY (a .pub file,
18# default ~/.ssh/id_ed25519.pub). The key is shared with this VM only.
19set -euo pipefail
20cd "$(dirname "$(readlink -f "$0")")"
21here=$PWD
22
23if [ "${1:-}" = --fresh ]; then
24 rm -f desktop.qcow2
25fi
26
27# The first render node whose driver isn't nvidia.
28rendernode=
29for node in /dev/dri/renderD*; do
30 driver=$(basename "$(readlink -f "/sys/class/drm/$(basename "$node")/device/driver")")
31 if [ "$driver" != nvidia ]; then rendernode=$node; break; fi
32done
33if [ -z "$rendernode" ]; then
34 echo "No non-NVIDIA GPU found for the VM to render on." >&2
35 exit 1
36fi
37
38vm=$(nix build --no-link --print-out-paths .#nixosConfigurations.desktop.config.system.build.vm)
39
40# Outside NixOS (e.g. on CachyOS, before the switch) there is no
41# /run/opengl-driver for the Nix-built QEMU to find GPU drivers in; give it the
42# Mesa from the same nixpkgs.
43if [ ! -e /run/opengl-driver ]; then
44 mesa=$(nix build --no-link --print-out-paths .#nixosConfigurations.desktop.pkgs.mesa)
45 export GBM_BACKENDS_PATH=$mesa/lib/gbm
46 export LIBGL_DRIVERS_PATH=$mesa/lib/dri
47 export __EGL_VENDOR_LIBRARY_FILENAMES=$mesa/share/glvnd/egl_vendor.d/50_mesa.json
48fi
49export NIX_DISK_IMAGE="$here/desktop.qcow2"
50
51# A temporary folder for the VM's sockets and /tmp/xchg, with the SSH key in it.
52vmtmp=$(mktemp -d -t dot-vm.XXXXXXXX)
53trap 'rm -rf -- "${vmtmp:?}"' EXIT
54export TMPDIR=$vmtmp USE_TMPDIR=1
55mkdir -p "$vmtmp/xchg"
56key=${VM_SSH_KEY:-$HOME/.ssh/id_ed25519.pub}
57if [ -f "$key" ]; then install -m644 "$key" "$vmtmp/xchg/authorized_keys"; fi
58export QEMU_OPTS="${QEMU_OPTS:-} -display egl-headless,rendernode=$rendernode -vnc 127.0.0.1:5 -k no -monitor unix:$here/vm-monitor.sock,server,nowait -serial file:$here/vm-serial.log"
59echo "VM starting; watch it with: vncviewer localhost:5905"
60"$vm/bin/run-desktop-vm"