Add initial QVM CLI, Nix flake, scripts and README

This commit is contained in:
Joshua Bell 2026-01-26 00:16:18 -06:00
parent 25b1cca0e6
commit 8534f7efb9
14 changed files with 2359 additions and 0 deletions

212
flake/default-vm/flake.nix Normal file
View file

@ -0,0 +1,212 @@
{
description = "Default NixOS VM template for QVM development environments";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
opencode.url = "github:anomalyco/opencode";
};
outputs = {
self,
nixpkgs,
nixos-generators,
home-manager,
opencode,
...
}: let
system = "x86_64-linux";
stateVersion = "24.11";
vmModule = { config, pkgs, lib, ... }: {
imports = [
home-manager.nixosModules.home-manager
];
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;
# Starship prompt that shows we're in qvm-dev
programs.starship = {
enable = true;
settings = {
add_newline = false;
format = lib.concatStrings [
"[](bold green)"
"[$hostname](bold red)"
"[$directory](bold blue)"
"$git_branch"
"$git_status"
"\n"
"[>](bold green) "
];
hostname = {
ssh_only = false;
format = "[@$hostname](bold red) ";
disabled = false;
};
};
};
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
};
};
};
# 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
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
'';
# 20GB disk size
virtualisation.diskSize = 20 * 1024;
system.stateVersion = stateVersion;
};
in {
# Export the qcow2 image
packages.${system}.qcow2 = nixos-generators.nixosGenerate {
inherit system;
format = "qcow";
modules = [ vmModule ];
};
# Also export a default package
packages.${system}.default = self.packages.${system}.qcow2;
# Export the module for reuse
nixosModules.default = vmModule;
};
}