{ hostName, ipAddress, tapId, mac, }: { pkgs, lib, ... }: let workspace = "/x/vm/${hostName}"; in { networking.hostName = hostName; time.timeZone = "Europe/London"; system.stateVersion = "26.05"; # GC of the shared lower store creates persistent overlayfs whiteouts. nix.gc.automatic = lib.mkForce false; microvm = { hypervisor = "qemu"; vcpu = 4; mem = 8192; interfaces = [ { type = "tap"; id = tapId; inherit mac; } ]; writableStoreOverlay = "/nix/.rw-store"; # whole-disk persistent root; sparse image under /var/lib/microvms// volumes = [ { image = "root.img"; mountPoint = "/"; size = 81920; label = "${hostName}-root"; } ]; shares = [ { proto = "virtiofs"; tag = "ro-store"; source = "/nix/store"; mountPoint = "/nix/.ro-store"; } { proto = "virtiofs"; tag = "ssh-keys"; source = "/var/lib/microvms/${hostName}/ssh-host-keys"; mountPoint = "/etc/ssh/host-keys"; } { proto = "virtiofs"; tag = "user-ssh-keys"; source = "/var/lib/microvms/${hostName}/ssh-user-keys"; mountPoint = "/etc/ssh/user-keys"; } # tailscaled state must persist or the node re-registers on every boot { proto = "virtiofs"; tag = "tailscale-state"; source = "/var/lib/microvms/${hostName}/tailscale"; mountPoint = "/var/lib/tailscale"; } { proto = "virtiofs"; tag = "pi-agent"; source = "/home/charlotte/.pi/agent"; mountPoint = "/home/charlotte/.pi/agent"; } # ~/.pi/agent/extensions symlinks into here { proto = "virtiofs"; tag = "personal-dotfiles"; source = "/home/charlotte/.personal-dotfiles"; mountPoint = "/home/charlotte/.personal-dotfiles"; } { proto = "virtiofs"; tag = "nixos-system"; source = "/home/charlotte/.nixos-system"; mountPoint = "/home/charlotte/.nixos-system"; } { proto = "virtiofs"; tag = "workspace"; source = workspace; mountPoint = "/x"; } ]; }; boot.loader.systemd-boot.enable = lib.mkForce false; boot.loader.efi.canTouchEfiVariables = lib.mkForce false; networking.useNetworkd = true; networking.useDHCP = false; networking.firewall.enable = false; systemd.network.enable = true; systemd.network.wait-online.enable = lib.mkForce true; systemd.network.networks."20-lan" = { matchConfig.Type = "ether"; address = [ "${ipAddress}/16" ]; networkConfig.Gateway = "10.11.0.1"; networkConfig.DNS = [ "10.11.0.1" ]; networkConfig.IPv6AcceptRA = true; }; services.openssh.hostKeys = [ { path = "/etc/ssh/host-keys/ssh_host_ed25519_key"; type = "ed25519"; } ]; users.users.charlotte = { isNormalUser = true; # virtiofs passes uids through raw; must match the host user uid = 1000; description = "charlotte"; extraGroups = [ "wheel" ]; shell = pkgs.zsh; openssh.authorizedKeys.keyFiles = [ (pkgs.fetchurl { url = "https://char.lt/ssh.txt"; hash = "sha256-5rwSdpfUJIB9KlQp2Xw6m02/0uc9TUV0/zBgrg0nCik="; }) ]; }; systemd.services.persist-user-ssh-key = { description = "Provision charlotte's persistent ssh key"; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; path = [ pkgs.openssh ]; script = '' install -d -m 0700 -o charlotte -g users /home/charlotte/.ssh if [ ! -f /etc/ssh/user-keys/id_ed25519 ]; then ssh-keygen -t ed25519 -N "" -C "charlotte@${hostName}" -f /etc/ssh/user-keys/id_ed25519 fi chown charlotte:users /etc/ssh/user-keys/id_ed25519{,.pub} chmod 600 /etc/ssh/user-keys/id_ed25519 ln -sf /etc/ssh/user-keys/id_ed25519{,.pub} /home/charlotte/.ssh/ ''; }; }