{ description = "Default NixOS VM template for QVM development environments"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; home-manager = { url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; nixos-generators = { url = "github:nix-community/nixos-generators"; inputs.nixpkgs.follows = "nixpkgs"; }; opencode.url = "github:anomalyco/opencode"; common.url = "git+https://git.joshuabell.xyz/ringofstorms/dotfiles?dir=flakes/common"; ros_neovim.url = "git+https://git.joshuabell.xyz/ringofstorms/nvim"; }; outputs = { self, nixpkgs, nixos-generators, ... }@inputs: let system = "x86_64-linux"; stateVersion = "26.05"; vmModule = { config, pkgs, lib, ... }: { imports = [ inputs.home-manager.nixosModules.home-manager inputs.ros_neovim.nixosModules.default inputs.common.nixosModules.essentials inputs.common.nixosModules.git inputs.common.nixosModules.zsh inputs.common.nixosModules.tmux ]; nixpkgs.config = { allowUnfree = true; allowUnfreePredicate = (_: true); }; # Distinctive hostname for easy identification networking.hostName = "qvm-dev"; # SSH enabled with password auth for root services.openssh = { enable = true; settings.PasswordAuthentication = true; settings.PermitRootLogin = "yes"; }; # Root user with password and zsh users.users.root = { password = "root"; shell = pkgs.zsh; }; programs.zsh.enable = true; # Home manager configuration for nice shell home-manager = { useUserPackages = true; useGlobalPkgs = true; backupFileExtension = "bak"; users.root = { home.stateVersion = stateVersion; programs.home-manager.enable = true; sharedModules = [ inputs.common.homeManagerModules.atuin inputs.common.homeManagerModules.git inputs.common.homeManagerModules.postgres_cli_options inputs.common.homeManagerModules.starship inputs.common.homeManagerModules.zoxide inputs.common.homeManagerModules.zsh inputs.common.homeManagerModules.tmux inputs.common.homeManagerModules.direnv ]; }; }; # Avoid slow boots due to wait-online systemd.network.wait-online.enable = false; systemd.services.NetworkManager-wait-online.enable = lib.mkForce false; systemd.services.systemd-networkd-wait-online.enable = lib.mkForce false; networking.firewall.allowedTCPPorts = [ 22 ]; # Enable flakes nix.settings.experimental-features = [ "nix-command" "flakes" ]; # Josh's timezone time.timeZone = "America/Chicago"; # Git safe.directory for 9p ownership issues environment.etc."gitconfig".text = '' [safe] directory = * ''; # 9p mount points for caches (must match qvm-start mount tags) fileSystems."/cache/cargo" = { device = "cargo_home"; fsType = "9p"; options = [ "trans=virtio" "version=9p2000.L" "msize=104857600" "_netdev" "nofail" ]; }; fileSystems."/cache/target" = { device = "cargo_target"; fsType = "9p"; options = [ "trans=virtio" "version=9p2000.L" "msize=104857600" "_netdev" "nofail" ]; }; fileSystems."/cache/pnpm" = { device = "pnpm_store"; fsType = "9p"; options = [ "trans=virtio" "version=9p2000.L" "msize=104857600" "_netdev" "nofail" ]; }; fileSystems."/cache/sccache" = { device = "sccache"; fsType = "9p"; options = [ "trans=virtio" "version=9p2000.L" "msize=104857600" "_netdev" "nofail" ]; }; # Environment variables for cache directories environment.variables = { CARGO_HOME = "/cache/cargo"; CARGO_TARGET_DIR = "/cache/target"; PNPM_HOME = "/cache/pnpm"; SCCACHE_DIR = "/cache/sccache"; }; # Ensure workspace directory exists systemd.tmpfiles.rules = [ "d /workspace 0755 root root -" ]; # Essential packages for development environment.systemPackages = with pkgs; [ git vim tmux htop curl jq ripgrep fd inputs.opencode.packages.${system}.default ]; # Opencode aliases without proxy interference environment.shellAliases = { "oc" = "all_proxy='' http_proxy='' https_proxy='' opencode"; "occ" = "oc -c"; }; # MOTD to clearly show this is qvm-dev users.motd = '' ╔════════════════════════════════════════╗ ║ ║ ║ QVM Development VM ║ ║ Hostname: qvm-dev ║ ║ ║ ║ Caches: /cache/{cargo,target,...} ║ ║ Workspace: /workspace ║ ║ ║ ╚════════════════════════════════════════╝ ''; # 35GB disk size virtualisation.diskSize = 40 * 1024; system.stateVersion = stateVersion; }; in let qcow2Image = nixos-generators.nixosGenerate { inherit system; format = "qcow"; modules = [ vmModule ]; }; in { # Export the qcow2 image packages.${system} = { qcow2 = qcow2Image; default = qcow2Image; }; # Export the module for reuse nixosModules.default = vmModule; }; }