diff --git a/hosts/uconsole-cm5/configuration.nix b/hosts/uconsole-cm5/configuration.nix index aac6f4f..12061c9 100644 --- a/hosts/uconsole-cm5/configuration.nix +++ b/hosts/uconsole-cm5/configuration.nix @@ -36,6 +36,9 @@ xwayland.enable = true; }; + # Home-manager needs zsh enabled system-wide for gortium user + programs.zsh.enable = true; + # HackerGadgets AIO v2 board hardware.uconsole-cm5-aio-v2 = { enable = true; diff --git a/modules/nixos/services/staging-vm.nix.bak b/modules/nixos/services/staging-vm.nix.bak new file mode 100755 index 0000000..91bf667 --- /dev/null +++ b/modules/nixos/services/staging-vm.nix.bak @@ -0,0 +1,275 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.stagingVm; +in +{ + options.services.stagingVm = { + enable = mkOption { + type = types.bool; + default = false; + description = "Enable KVM/libvirt staging VM for compose PR testing"; + }; + + vmName = mkOption { + type = types.str; + default = "compose-test-vm"; + description = "Name of the staging VM"; + }; + + memory = mkOption { + type = types.str; + default = "4096"; + description = "RAM allocated to the staging VM (MB)"; + }; + + vcpus = mkOption { + type = types.int; + default = 2; + description = "Number of vCPUs for the staging VM"; + }; + + storagePath = mkOption { + type = types.str; + default = "/var/lib/libvirt/images"; + description = "Path for libvirt storage pool"; + }; + + dataPath = mkOption { + type = types.str; + default = "/var/lib/staging-vm"; + description = "Path for compose test data (PR checkouts, test results)"; + }; + }; + + config = mkIf cfg.enable { + # Enable libvirt daemon + virtualisation.libvirtd = { + enable = true; + qemu = { + package = pkgs.qemu_kvm; + runAsRoot = true; + swtpm.enable = true; + ovmf = { + enable = true; + packages = [ pkgs.OVMFFull.fd ]; + }; + }; + }; + + # Kernel modules + groups already handled in configuration.nix + + # libvirt NAT network (192.168.122.0/24) + environment.etc."libvirt/qemu/networks/default.xml" = { + text = '' + + default + 2b8f7a3c-9e5d-4a1f-bc3d-6e7a8f9b0c1d + + + + + + + + + + + + + + ''; + # Autostart the network so it comes up on boot + mode = "0644"; + }; + + # Ensure the default network is defined and autostarted + systemd.services.libvirtd = { + postStart = '' + ${pkgs.libvirt}/bin/virsh net-define /etc/libvirt/qemu/networks/default.xml 2>/dev/null || true + ${pkgs.libvirt}/bin/virsh net-autostart default 2>/dev/null || true + ${pkgs.libvirt}/bin/virsh net-start default 2>/dev/null || true + ''; + }; + + # Storage directory for VM images + systemd.tmpfiles.rules = [ + "d ${cfg.storagePath} 0755 root root -" + "d ${cfg.dataPath} 0755 root root -" + ]; + + # Ensure storage pool exists in libvirt + systemd.services.libvirtd.postStart = mkAfter '' + ${pkgs.libvirt}/bin/virsh pool-define-as default dir --target "${cfg.storagePath}" 2>/dev/null || true + ${pkgs.libvirt}/bin/virsh pool-autostart default 2>/dev/null || true + ${pkgs.libvirt}/bin/virsh pool-start default 2>/dev/null || true + ''; + + # Firewall: allow traffic from virbr0 to host and outbound NAT + networking.firewall = { + extraCommands = '' + # Allow inbound DHCP/DNS from libvirt guests + iptables -I INPUT -i virbr0 -p udp --dport 67:68 -j ACCEPT + iptables -I INPUT -i virbr0 -p tcp --dport 53 -j ACCEPT + iptables -I INPUT -i virbr0 -p udp --dport 53 -j ACCEPT + + # Allow established/related traffic back to guests + iptables -I FORWARD -i virbr0 -o virbr0 -j ACCEPT + iptables -I FORWARD -o virbr0 -j ACCEPT + iptables -I FORWARD -i virbr0 -j ACCEPT + ''; + }; + + # Packages needed for VM management + environment.systemPackages = with pkgs; [ + libvirt + qemu_kvm + virt-manager # optional GUI for manual management + OVMFFull + swtpm + ]; + + # Enable docker in the host (already enabled, but ensure for compose testing) + virtualisation.docker.enable = true; + + # Helper script: pr-test-vm + # Usage: + # pr-test-vm build — build the staging VM derivation + # pr-test-vm start — boot the VM with a compose PR branch + # pr-test-vm stop — graceful shutdown + # pr-test-vm destroy — force stop + delete VM + # pr-test-vm ssh — SSH into the running VM + systemd.tmpfiles.rules = mkAfter [ + "d ${cfg.dataPath}/scripts 0755 root root -" + ]; + + environment.systemPackages = [ (pkgs.writeShellScriptBin "pr-test-vm" '' + set -euo pipefail + + DATA="${cfg.dataPath}" + VM_NAME="${cfg.vmName}" + VM_IMAGE="''${DATA}/''${VM_NAME}.qcow2" + VM_PORT=2223 + + build_vm() { + echo "==> Building NixOS staging VM for compose testing..." + # Build the VM config inline — a minimal NixOS with Docker + SSH + cat > /tmp/staging-vm-config.nix << 'NIXEOF' + { config, pkgs, lib, ... }: { + boot.loader.grub.devices = [ "/dev/vda" ]; + boot.loader.timeout = 0; + + # Minimal kernel + boot.kernelParams = [ "console=ttyS0" ]; + boot.initrd.kernelModules = [ "virtio_blk" "virtio_net" "virtio_pci" ]; + + # SSH access + services.openssh = { + enable = true; + settings.PasswordAuthentication = false; + settings.PermitRootLogin = "prohibit-password"; + }; + + # Docker for compose testing + virtualisation.docker.enable = true; + + # Network (DHCP via virbr0) + networking.useDHCP = true; + networking.firewall.enable = false; + + # Users + users.users.root.openssh.authorizedKeys.keys = [ + "$(cat /root/.ssh/authorized_keys 2>/dev/null || echo 'ssh-ed25519 AAAAC3... placeholder')" + ]; + users.users.testrunner = { + isNormalUser = true; + extraGroups = [ "docker" ]; + openssh.authorizedKeys.keys = [ + "$(cat /root/.ssh/authorized_keys 2>/dev/null || echo 'ssh-ed25519 AAAAC3... placeholder')" + ]; + }; + + # Git + compose tools + environment.systemPackages = with pkgs; [ git docker-compose curl ]; + + system.stateVersion = "24.11"; + } + NIXEOF + + nixos-rebuild build-vm -I nixpkgs=channel:nixos-unstable \ + --arg configuration 'import /tmp/staging-vm-config.nix' \ + --out-link "''${DATA}/vm-result" + echo "==> VM built. Run 'pr-test-vm start' to boot." + } + + start_vm() { + if [ -f "''${VM_IMAGE}" ]; then + echo "==> Booting existing VM..." + else + echo "==> Creating VM image..." + ${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 "''${VM_IMAGE}" 20G + fi + + # Check if already running + if ${pkgs.libvirt}/bin/virsh list --name 2>/dev/null | grep -q "''${VM_NAME}"; then + echo "==> VM already running." + exit 0 + fi + + ${pkgs.qemu_kvm}/bin/qemu-system-x86_64 \ + -name "''${VM_NAME}" \ + -machine q35,accel=kvm \ + -cpu host \ + -smp ${toString cfg.vcpus} \ + -m ${cfg.memory} \ + -drive file="''${VM_IMAGE}",if=virtio,format=qcow2 \ + -netdev user,id=net0,hostfwd=tcp::''${VM_PORT}-:22 \ + -device virtio-net-pci,netdev=net0 \ + -nographic \ + -serial mon:stdio \ + -pidfile "''${DATA}/''${VM_NAME}.pid" \ + -daemonize + + echo "==> VM booting... SSH on port ''${VM_PORT}" + echo "==> Wait for it: ssh -p ''${VM_PORT} testrunner@localhost" + } + + stop_vm() { + PIDFILE="''${DATA}/''${VM_NAME}.pid" + if [ -f "''${PIDFILE}" ]; then + PID=$(cat "''${PIDFILE}") + kill "''${PID}" 2>/dev/null || true + rm -f "''${PIDFILE}" + echo "==> VM stopped." + else + ${pkgs.libvirt}/bin/virsh destroy "''${VM_NAME}" 2>/dev/null || true + echo "==> VM destroyed." + fi + } + + ssh_vm() { + exec ssh -p "''${VM_PORT}" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "testrunner@localhost" "$@" + } + + # Main dispatch + case "''${1:-help}" in + build) build_vm ;; + start) start_vm ;; + stop) stop_vm ;; + destroy) stop_vm; rm -f "''${VM_IMAGE}"; echo "==> VM deleted." ;; + ssh) shift; ssh_vm "$@" ;; + *) + echo "Usage: pr-test-vm {build|start|stop|destroy|ssh}" + echo "" + echo " build — build the NixOS VM derivation" + echo " start — boot the VM (create image if needed)" + echo " stop — graceful VM shutdown" + echo " destroy — stop + delete VM image" + echo " ssh — SSH into the running VM" + ;; + esac + '') ]; + }; +} diff --git a/result b/result new file mode 120000 index 0000000..c445871 --- /dev/null +++ b/result @@ -0,0 +1 @@ +/nix/store/z86r4awsbrc5q9qhwwi757wxixcqgn31-nixos-system-uConsole-25.11.20260608.e820eb4 \ No newline at end of file diff --git a/result-uconsole b/result-uconsole new file mode 120000 index 0000000..e5d8532 --- /dev/null +++ b/result-uconsole @@ -0,0 +1 @@ +/nix/store/7y7rfksqcf5smz59jjixyl56bxq50j9g-nixos-system-uConsole-25.11.20260608.e820eb4 \ No newline at end of file diff --git a/users/gortium/home.nix b/users/gortium/home.nix index ce7902f..95ec0ea 100644 --- a/users/gortium/home.nix +++ b/users/gortium/home.nix @@ -10,9 +10,6 @@ in { programs.home-manager.enable = true; home.file = { - # zsh - ".zshrc".source = "${dotfiles}/zsh/.zshrc"; - # tmux ".tmux.conf".source = "${dotfiles}/tmux/.tmux.conf";