{ lib, config, modulesPath, pkgs, ... }: let inherit (lib) mkOption types concatStringsSep; jsonType = (pkgs.formats.json { }).type; inherit (config.system.build) initialRamdisk; inherit (config.system.boot.loader) initrdFile; inherit (config.boot.kernelPackages) kernel; kernelTarget = pkgs.stdenv.hostPlatform.linux-kernel.target; uvmsPkgs = pkgs.callPackage ../pkgs { }; waylandSock = "/run/user/1000/wayland-1"; env = { XDG_RUNTIME_DIR = "/run/user/1000"; WAYLAND_DISPLAY = "wayland-1"; # MESA_LOADER_DRIVER_OVERRIDE = "zink"; ELECTRON_OZONE_PLATFORM_HINT = "wayland"; MOZ_ENABLE_WAYLAND = "1"; QT_QPA_PLATFORM = "wayland"; # Qt Applications GDK_BACKEND = "wayland"; # GTK Applications XDG_SESSION_TYPE = "wayland"; # Electron Applications SDL_VIDEODRIVER = "wayland"; CLUTTER_BACKEND = "wayland"; NIXOS_OZONE_WL = "1"; }; in { imports = [ (modulesPath + "/profiles/minimal.nix") ./debug-closure.nix ./minimal.nix ./on-failure.nix ]; config = { some.failure-handler.enable = true; hardware.graphics.enable = true; # boot.kernelPackages = pkgs.linuxPackagesFor uvmsPkgs.linux-uvm; # boot.isContainer = true; boot.initrd.kernelModules = [ "drm" "virtio_blk" "virtiofs" "virtio_gpu" "virtio_mmio" "virtio_pci" "overlay" ]; boot.kernelModules = [ "drm" "erofs" "overlay" "virtio_blk" "virtiofs" "virtio_gpu" "virtio_mmio" "virtio_pci" ]; boot.initrd.systemd.initrdBin = [ pkgs.fuse pkgs.fuse3 ]; fileSystems = { "/" = lib.mkDefault { device = "rootfs"; # how does this work? does this assign a label to the tmpfs? fsType = "tmpfs"; options = [ "size=20%,mode=0755" ]; neededForBoot = true; }; "/nix/store" = { fsType = "overlay"; overlay.lowerdir = [ "/nix/.ro-stores/system" "/nix/.ro-stores/apps" ]; neededForBoot = true; }; "/nix/.ro-stores/system" = { device = "system"; fsType = "virtiofs"; options = [ "defaults" "ro" "x-systemd.requires=systemd-modules-load.service" ]; neededForBoot = true; }; "/nix/.ro-stores/apps" = { device = "apps"; fsType = "virtiofs"; options = [ "defaults" "ro" "x-systemd.requires=systemd-modules-load.service" ]; neededForBoot = true; }; }; systemd.mounts = [ { type = "virtiofs"; where = "/home/user"; what = "home"; after = [ "systemd-modules-load.service" ]; wantedBy = [ "local-fs.target" ]; before = [ "local-fs.target" ]; requires = [ "systemd-modules-load.service" ]; options = lib.concatStringsSep "," [ "defaults" "rw" "X-mount.owner=1000" "X-mount.group=100" ]; unitConfig = { ConditionKernelCommandLine = "uvms.persist-home=1"; }; } { type = "virtiofs"; where = "/home/user/send"; what = "send"; wants = [ "home-user.mount" "-.mount" ]; after = [ "systemd-modules-load.service" "home-user.mount" "-.mount" ]; wantedBy = [ "local-fs.target" ]; before = [ "local-fs.target" ]; options = lib.concatStringsSep "," [ "defaults" "rw" "X-mount.owner=1000" "X-mount.group=100" ]; unitConfig = { DefaultDependencies = false; }; } ]; # systemd.services."mount-home-user-send" = { # wants = [ "home-user.mount" ]; # after = [ # "systemd-modules-load.service" # "home-user.mount" # "-.mount" # ]; # wantedBy = [ "local-fs.target" ]; # before = [ "local-fs.target" ]; # unitConfig = { # DefaultDependencies = false; # }; # environment.PATH = lib.mkForce ( # lib.makeBinPath [ # pkgs.fuse # pkgs.fuse3 # pkgs.coreutils # ] # ); # serviceConfig = { # Type = "oneshot"; # RemainsAfterExit = true; # ExecStart = [ # "/run/current-system/sw/bin/mkdir -p /home/user/send" # "/run/current-system/sw/bin/chown user /home/user/send" # "/run/current-system/sw/sbin/mount -t virtiofs -o defaults,rw send /home/user/send" # ]; # StandardOutput = "journal+console"; # StandardError = "journal+console"; # }; # }; systemd.network.enable = true; networking.useNetworkd = true; networking.nftables.enable = true; networking.useDHCP = true; networking.nameservers = [ "1.1.1.1" ]; services.resolved.enable = lib.mkForce true; system.activationScripts.specialfs = lib.mkForce ""; # networking.firewall.enable = false; console.enable = false; services.udev.packages = lib.mkDefault [ ]; systemd.services."systemd-oomd".enable = false; users.mutableUsers = false; users.users.root.password = "hacktheplanet!"; users.groups.users = { }; users.users.user = { uid = 1000; isNormalUser = true; password = "hacktheplanet!"; extraGroups = [ "video" "render" "users" "wheel" ]; }; environment.variables = env; systemd.globalEnvironment = env; systemd.tmpfiles.settings."10-xdg" = { ${env.XDG_RUNTIME_DIR}.d = { user = "user"; group = "users"; mode = "0755"; }; }; systemd.sockets."wayland-proxy" = { listenStreams = [ waylandSock ]; socketConfig = { SocketUser = "user"; SocketGroup = "users"; FileDescriptorName = "wayland"; }; wantedBy = [ "sockets.target" ]; partOf = [ "wayland-proxy.service" ]; }; systemd.services."wayland-proxy" = { wantedBy = [ "default.target" ]; serviceConfig = { User = "user"; Group = "users"; ExecStart = "${lib.getExe pkgs.wayland-proxy-virtwl} --virtio-gpu"; # ExecStart = "${lib.getExe uvmsPkgs.wl-cross-domain-proxy} --listen-fd --filter-global wp_presentation"; ExecStartPre = [ "+/run/current-system/sw/bin/chmod 0666 /dev/dri/card0 /dev/dri/renderD128" ]; StandardOutput = "journal+console"; StandardError = "journal+console"; Restart = "on-failure"; RestartSec = 5; }; }; systemd.sockets."uvms-guest" = { wantedBy = [ "default.target" ]; listenStreams = [ "vsock::24601" ]; partOf = [ "uvms-guest.service" ]; }; systemd.services."uvms-guest" = { serviceConfig = { User = "user"; Group = "users"; ExecStart = "${lib.getExe uvmsPkgs.uvms-guest}"; StandardOutput = "journal+console"; StandardError = "journal+console"; Restart = "on-failure"; RestartSec = 5; }; }; fonts.enableDefaultPackages = true; boot.kernelParams = [ "earlyprintk=ttyS0" "console=ttyS0" "reboot=t" "panic=-1" "io.systemd.credential:vmm.notify_socket=vsock-stream:2:8888" # "rootfstype=virtiofs" # "root=rootstore" ]; }; options = { system.build.ch = mkOption { type = types.package; default = (pkgs.formats.json { }).generate "vm.json" config.uvms.ch.settings; }; uvms.ch.settings = mkOption { default = { }; type = types.submodule { freeformType = jsonType; options = { payload = { cmdline = mkOption { type = types.str; default = concatStringsSep " " ( config.boot.kernelParams ++ [ # "init=${lib.removePrefix "/nix/store" "${config.system.build.toplevel}"}/init" "init=${config.system.build.toplevel}/init" ] ); defaultText = ''concatStringsSep " " ${config.boot.kernelParams}''; }; kernel = mkOption { type = types.str; default = "${kernel}/${kernelTarget}"; }; initramfs = mkOption { type = types.nullOr types.str; default = "${initialRamdisk}/${initrdFile}"; }; }; vsock = { cid = mkOption { type = types.int; default = 4; }; socket = mkOption { type = types.str; default = "vsock.sock"; }; }; "api-socket" = mkOption { type = types.str; default = "vmm.sock"; }; "serial".mode = mkOption { type = types.str; default = "File"; }; "serial".file = mkOption { type = types.nullOr types.str; default = "serial"; }; "console".mode = mkOption { type = types.str; default = "Pty"; }; "console".file = mkOption { type = types.nullOr types.str; default = null; }; # "watchdog" = true; # "seccomp" = true; disks = mkOption { default = [ ]; type = types.listOf ( types.submodule { freeformType = jsonType; options = { path = mkOption { type = types.oneOf [ types.path types.str ]; }; readonly = mkOption { type = types.bool; default = true; }; id = mkOption { type = types.str; }; }; } ); }; memory = mkOption { default = { }; type = types.submodule { freeformType = jsonType; options = { size = mkOption { type = types.int; default = 1536 * 1048576; }; shared = mkOption { type = types.bool; default = true; }; mergeable = mkOption { type = types.bool; default = true; }; }; }; }; cpus = mkOption { default = { }; type = types.submodule { freeformType = jsonType; options = { boot_vcpus = mkOption { type = types.int; default = 4; }; max_vcpus = mkOption { type = types.int; default = 4; }; }; }; }; }; }; }; }; }