# vm.nix let pkgs = import {}; in let # 1. SOURCE YOUR DEBIAN IMAGE debianImage = pkgs.fetchurl { name = "debian-13-genericcloud-amd64.qcow2"; url = "https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2"; hash = "sha256-V9a6DUghJB5j4Vz9Y5aikZ8syhx5Zn2593m8/8xNwIU="; }; # 2. VM DATA DIRECTORY vmDataDir = "/home/${builtins.getEnv "USER"}/.local/share/debian-vm"; # 3. CREATE ALL FILES IN A SCRIPT setupScript = pkgs.writeShellScriptBin "setup-vm-files" '' set -e # Create VM directory mkdir -p "${vmDataDir}" # Create persistent disk if it doesn't exist (with 20GB initial size) if [ ! -f "${vmDataDir}/debian-persistent.qcow2" ]; then echo "Creating persistent disk from base image..." ${pkgs.qemu}/bin/qemu-img create -f qcow2 \ -b "${debianImage}" \ -F qcow2 \ "${vmDataDir}/debian-persistent.qcow2" \ 20G fi # Create cloud-init configuration cat > "${vmDataDir}/user-data" << 'EOF' #cloud-config # User configuration users: - name: debian sudo: ALL=(ALL) NOPASSWD:ALL groups: sudo, users, adm, video, render shell: /bin/bash lock_passwd: false passwd: nixos system: false create_groups: true # Enable password authentication ssh_pwauth: true chpasswd: expire: false list: | debian:nixos root:nixos # Update system package_update: true package_upgrade: true # Install packages - ADDED GPU DRIVERS packages: - git - firefox-esr - sway - sudo - curl - wget # GPU/Display drivers - mesa-vulkan-drivers - libgl1-mesa-dri - xwayland - seatd # Utilities - dbus-x11 - xdg-utils - policykit-1 # Write setup script write_files: - path: /home/debian/first-boot-setup.sh owner: debian:debian permissions: '0755' content: | #!/bin/bash set -e echo "Starting first-boot setup as debian user..." # Enable seatd service for non-systemd login sudo systemctl enable seatd || true sudo systemctl start seatd || true # Add user to necessary groups for Wayland sudo usermod -a -G video,render,seat,input debian # Clone repository cd /home/debian echo "Cloning GRCon23Tutorial repository..." git clone https://github.com/ARDC-TOBB-ETU/GRCon23Tutorial --depth=1 # Run installation cd GRCon23Tutorial echo "Running installation script..." chmod +x install.sh ./install.sh cat > ~/start-sway.sh << 'LAUNCHEREOF' #!/bin/bash # Start a bare X server with a virtual display Xorg :10 -ac -screen 1024x768 & XPID=$! # Set the DISPLAY environment variable for the new X server export DISPLAY=:10 # Wait for X to be ready, then start Sway using XWayland sleep 2 dbus-run-session sway --unsupported-gpu # Cleanup: when Sway exits, kill the X server kill $XPID LAUNCHEREOF chmod +x ~/start-sway.sh echo "Created launcher script: ~/start-sway.sh" echo "First-boot setup completed!" echo "Installed packages:" dpkg -l git firefox-esr sway mesa-vulkan-drivers | grep ^ii # Create marker file sudo touch /etc/vm-initialized echo "User setup completed at $(date)" | sudo tee -a /var/log/vm-init.log # Run commands runcmd: # Configure sudo - [sed, -i, '/^%sudo/s/ALL$/NOPASSWD:ALL/', /etc/sudoers] # Create log directory - [mkdir, -p, /var/log] # Update and install packages - [apt-get, update] - [apt-get, install, -y, git, firefox-esr, sway, sudo, mesa-vulkan-drivers, libgl1-mesa-dri, xwayland, seatd, dbus-x11] # Set up user environment - [chown, -R, debian:debian, /home/debian] - [chmod, 700, /home/debian] # Enable services - [systemctl, enable, seatd] - [systemctl, start, seatd] # Run user setup - [sudo, -u, debian, /bin/bash, /home/debian/first-boot-setup.sh] # Final setup - [echo, "VM setup completed at $(date)", ">>", /var/log/vm-init.log] - [echo, "User groups:", ">>", /var/log/vm-init.log] - [groups, debian, ">>", /var/log/vm-init.log] # Final message final_message: | VM initialization complete! For Sway/Wayland to work: 1. The VM needs GPU acceleration 2. User 'debian' added to video, render, seat groups 3. seatd service enabled for Wayland sessions Login with: Username: debian Password: nixos To start Sway manually: sway --unsupported-gpu Or SSH and run: dbus-run-session sway Important: Sway is installed but requires a workaround for the virtual environment. To start Sway: 1. SSH into the VM: ssh debian@localhost -p 2222 2. Run the launcher script: ~/start-sway.sh This script starts an X server and runs Sway within it using XWayland. The display will be accessible via the QEMU GTK window. EOF # Create cloud-init ISO ${pkgs.cloud-utils}/bin/cloud-localds \ "${vmDataDir}/cloud-init.iso" \ "${vmDataDir}/user-data" echo "VM files created in ${vmDataDir}" echo "First boot will set up GPU acceleration for Sway" ''; # 4. LAUNCH SCRIPT WITH GPU SUPPORT runScript = pkgs.writeShellScriptBin "run-debian-vm" '' set -e # Run setup first ${setupScript}/bin/setup-vm-files # Check if VM is already running if pgrep -f "debian-persistent.qcow2" > /dev/null; then echo "VM appears to be already running. Stopping it first..." pkill -f "debian-persistent.qcow2" sleep 2 fi echo "Starting Debian VM with GPU acceleration..." echo "" echo "GPU/Display configuration:" echo "- Using virtio-gpu-pci with OpenGL" echo "- User added to video, render groups" echo "- Mesa Vulkan drivers installed" echo "- seatd service enabled for Wayland" echo "" echo "After boot, to start Sway:" echo " SSH: ssh debian@localhost -p 2222" echo " Password: nixos" echo " Then run: dbus-run-session sway" echo " Or: sway --unsupported-gpu" echo "" echo "Press Ctrl+Alt+G to release mouse" # Launch QEMU with GPU acceleration ${pkgs.qemu_kvm}/bin/qemu-kvm \ -name "Debian-GRCon-VM" \ -machine q35,accel=kvm \ -cpu host,-hypervisor \ -smp 4 \ -m 4096 \ -drive file="${vmDataDir}/debian-persistent.qcow2",format=qcow2,if=virtio \ -drive file="${vmDataDir}/cloud-init.iso",format=raw,if=virtio \ -netdev user,id=n1,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=n1 \ # GPU CONFIGURATION: -device virtio-vga-gl \ -display gtk,gl=on \ -device virtio-keyboard-pci \ -device virtio-mouse-pci \ -device usb-tablet \ -audiodev pa,id=audio0,server=/run/user/1000/pulse/native \ -device AC97,audiodev=audio0 \ -vga none \ "$@" ''; in { system.build.customVM = runScript; }