{ pkgs , name ? "sandbox" , user ? "dummy" , config ? { } , restrictNetwork ? true # to be replaced with virtualisation.restrictNetwork , patchQemu9p ? false }: let # Patched QEMU to fix slow 9p file share. # https://linus.schreibt.jetzt/posts/qemu-9p-performance.html qemu_kvm_patched_9p = assert !(pkgs.lib.versionAtLeast pkgs.qemu_kvm.version "7.2.0"); pkgs.qemu_kvm.overrideAttrs (o: { patches = o.patches ++ [ (pkgs.fetchpatch { name = "qemu-9p-performance-fix.patch"; url = "https://github.com/qemu/qemu/commit/f5265c8.patch"; sha256 = "sha256-PSOv0dhiEq9g6B1uIbs6vbhGr7BQWCtAoLHnk4vnvVg="; }) ]; }); in rec { nixosConfigurations.${name} = pkgs.nixos ({ modulesPath, lib, pkgs, ... }: with lib; { imports = [ (modulesPath + "/profiles/minimal.nix") { environment.noXlibs = false; } # avoid mass rebuild (modulesPath + "/profiles/qemu-guest.nix") (modulesPath + "/virtualisation/qemu-vm.nix") config ]; system.stateVersion = mkDefault trivial.release; networking = { hostName = name; firewall.enable = mkDefault false; }; users.users.${user} = { isNormalUser = mkDefault true; password = mkDefault ""; extraGroups = mkDefault [ "wheel" ]; }; security.sudo.wheelNeedsPassword = mkDefault false; services.getty = { autologinUser = mkDefault user; helpLine = mkDefault '' Press to terminate the virtual machine. The working directory on the host is mounted to /mnt. ''; }; virtualisation = { graphics = mkDefault false; diskImage = mkDefault "$(mktemp).qcow2"; sharedDirectories.host = { source = "$SHARED_CWD"; target = "/mnt"; }; # Uncomment when this is merged: # https://github.com/NixOS/nixpkgs/pull/200225 #restrictNetwork = mkDefault true; qemu.package = mkDefault (if patchQemu9p then qemu_kvm_patched_9p else pkgs.qemu_kvm); }; }); packages.${name} = nixosConfigurations.${name}.config.system.build.vm; apps.${name} = { type = "app"; program = toString (pkgs.writeShellScript "sandbox-vm" ( (pkgs.lib.optionalString restrictNetwork '' # Isolate from network # Stopgap solution until this is merged: # https://github.com/NixOS/nixpkgs/pull/200225 QEMU_NET_OPTS="restrict=yes,''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" export QEMU_NET_OPTS '') + '' # Save current directory for mounting in VM SHARED_CWD=$PWD export SHARED_CWD ${packages.${name}}/bin/run-${name}-vm reset echo "Exited virtual machine." '')); }; }