flake.nix: extract packages/devshells/modules into smaller files
This commit is contained in:
parent
6f7f3f2461
commit
505e85b9c5
9 changed files with 360 additions and 323 deletions
16
devShells/default.nix
Normal file
16
devShells/default.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{ mkShell, lib, systemd, cargo, rust-analyzer, rustfmt, passt, bubblewrap, libkrun, muvm }:
|
||||||
|
|
||||||
|
let
|
||||||
|
projects = [ libkrun muvm ];
|
||||||
|
in mkShell {
|
||||||
|
MUVM_UDEVD_PATH = "${systemd}/lib/systemd/systemd-udevd";
|
||||||
|
nativeBuildInputs = lib.concatMap (pkg: pkg.nativeBuildInputs) projects;
|
||||||
|
buildInputs = (lib.concatMap (pkg: pkg.buildInputs) projects) ++ [
|
||||||
|
# virglrenderer
|
||||||
|
cargo
|
||||||
|
rust-analyzer
|
||||||
|
rustfmt
|
||||||
|
passt
|
||||||
|
bubblewrap
|
||||||
|
];
|
||||||
|
}
|
||||||
336
flake.nix
336
flake.nix
|
|
@ -9,248 +9,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils, virtwl, ... }: {
|
outputs = { self, nixpkgs, flake-utils, virtwl, ... }: {
|
||||||
nixosModules.testvm = { pkgs, ... }: {
|
nixosModules.testvm = nixpkgs.lib.modules.importApply ./nixosModules/testvm.nix { inherit virtwl; };
|
||||||
system.stateVersion = "25.11";
|
nixosModules.default = nixpkgs.lib.modules.importApply ./nixosModules/default.nix { inherit self virtwl; };
|
||||||
|
|
||||||
fonts.packages = [ pkgs.adwaita-fonts pkgs.dejavu_fonts ];
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.fastfetch
|
|
||||||
pkgs.htop
|
|
||||||
virtwl.packages.${pkgs.system}.proxy
|
|
||||||
pkgs.wayland-utils
|
|
||||||
pkgs.weston
|
|
||||||
pkgs.waycheck
|
|
||||||
pkgs.vulkan-tools
|
|
||||||
pkgs.glmark2
|
|
||||||
pkgs.mesa-demos
|
|
||||||
pkgs.xorg.xeyes
|
|
||||||
pkgs.xterm
|
|
||||||
# pkgs.vkquake # build broken: Program 'spirv-remap' not found
|
|
||||||
pkgs.veloren
|
|
||||||
pkgs.kdePackages.kate
|
|
||||||
pkgs.adwaita-icon-theme
|
|
||||||
pkgs.amberol
|
|
||||||
pkgs.bustle
|
|
||||||
pkgs.d-spy
|
|
||||||
pkgs.gnome-text-editor
|
|
||||||
pkgs.firefox
|
|
||||||
pkgs.ffmpeg-full
|
|
||||||
pkgs.mpv
|
|
||||||
pkgs.libva-utils
|
|
||||||
pkgs.tailscale
|
|
||||||
pkgs.zerotierone
|
|
||||||
pkgs.localsend
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
nixosModules.default = { pkgs, lib, utils, config, ... }: let
|
|
||||||
useTTY = {
|
|
||||||
TTYPath = "/dev/hvc0";
|
|
||||||
StandardOutput = "tty";
|
|
||||||
StandardInput = "tty";
|
|
||||||
StandardError = "tty";
|
|
||||||
};
|
|
||||||
runtimeDir = "/run/vm-user";
|
|
||||||
in {
|
|
||||||
boot.isContainer = true;
|
|
||||||
fileSystems."/".device = lib.mkDefault "/dev/sda"; # dummy
|
|
||||||
|
|
||||||
# Disable unused things
|
|
||||||
environment.defaultPackages = lib.mkDefault [ ];
|
|
||||||
documentation = {
|
|
||||||
enable = lib.mkDefault false;
|
|
||||||
doc.enable = lib.mkDefault false;
|
|
||||||
info.enable = lib.mkDefault false;
|
|
||||||
man.enable = lib.mkDefault false;
|
|
||||||
nixos.enable = lib.mkDefault false;
|
|
||||||
};
|
|
||||||
services.logrotate.enable = false;
|
|
||||||
services.udisks2.enable = false;
|
|
||||||
system.tools.nixos-generate-config.enable = false;
|
|
||||||
system.activationScripts.specialfs = lib.mkForce "";
|
|
||||||
systemd.coredump.enable = false;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
powerManagement.enable = false;
|
|
||||||
boot.kexec.enable = false;
|
|
||||||
console.enable = false;
|
|
||||||
|
|
||||||
# Configure activation / systemd
|
|
||||||
boot.initrd.systemd.enable = true; # for etc.overlay, but we don't have initrd
|
|
||||||
system.etc.overlay.enable = true; # erofs
|
|
||||||
system.etc.overlay.mutable = false;
|
|
||||||
systemd.sysusers.enable = true;
|
|
||||||
services.userborn.enable = false;
|
|
||||||
services.udev.enable = lib.mkDefault true;
|
|
||||||
services.udev.packages = lib.mkDefault [];
|
|
||||||
environment.etc."resolv.conf".text = "# to be overridden with mount";
|
|
||||||
environment.etc."machine-id".text = "# to be overridden with mount";
|
|
||||||
environment.etc."systemd/system".source = lib.mkForce (utils.systemdUtils.lib.generateUnits {
|
|
||||||
type = "system";
|
|
||||||
units = config.systemd.units;
|
|
||||||
upstreamUnits = [
|
|
||||||
"sysinit.target"
|
|
||||||
"local-fs.target"
|
|
||||||
"nss-user-lookup.target"
|
|
||||||
"umount.target"
|
|
||||||
"shutdown.target"
|
|
||||||
"reboot.target"
|
|
||||||
"exit.target"
|
|
||||||
"final.target"
|
|
||||||
"systemd-exit.service"
|
|
||||||
"systemd-journald.socket"
|
|
||||||
"systemd-journald-audit.socket"
|
|
||||||
"systemd-journald-dev-log.socket"
|
|
||||||
"systemd-journald.service"
|
|
||||||
"systemd-sysusers.service"
|
|
||||||
"systemd-udevd-kernel.socket"
|
|
||||||
"systemd-udevd-control.socket"
|
|
||||||
"systemd-udevd.service"
|
|
||||||
"systemd-tmpfiles-setup.service"
|
|
||||||
"user.slice"
|
|
||||||
];
|
|
||||||
upstreamWants = ["multi-user.target.wants"];
|
|
||||||
});
|
|
||||||
|
|
||||||
# systemd.package = pkgs.systemdMinimal; # no sysusers
|
|
||||||
systemd.defaultUnit = "microvm.target";
|
|
||||||
systemd.targets.microvm = {
|
|
||||||
description = "Minimal microVM system";
|
|
||||||
wants = ["systemd-journald.socket" "systemd-udevd.service" "dbus.socket"];
|
|
||||||
unitConfig.AllowIsolate = "yes";
|
|
||||||
};
|
|
||||||
systemd.services.systemd-remount-fs.enable = lib.mkForce false;
|
|
||||||
systemd.services.systemd-pstore.enable = lib.mkForce false;
|
|
||||||
systemd.services.lastlog2-import.enable = lib.mkForce false;
|
|
||||||
systemd.services.suid-sgid-wrappers.enable = lib.mkForce false;
|
|
||||||
systemd.services.systemd-sysusers.serviceConfig = {
|
|
||||||
ExecStartPre = lib.mkForce [];
|
|
||||||
ExecStartPost = lib.mkForce [];
|
|
||||||
};
|
|
||||||
systemd.services.microvm-nixos-activation = {
|
|
||||||
enable = true;
|
|
||||||
description = "NixOS Activation";
|
|
||||||
wantedBy = ["local-fs.target"];
|
|
||||||
before = ["systemd-tmpfiles-setup.service" "systemd-sysusers.service"];
|
|
||||||
requires = ["systemd-tmpfiles-setup.service" "systemd-sysusers.service"];
|
|
||||||
unitConfig.DefaultDependencies = false;
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
PassEnvironment = ["MICROVM_CLOSURE" "MICROVM_UID" "MICROVM_GID"];
|
|
||||||
} // useTTY;
|
|
||||||
script = ''
|
|
||||||
PATH=$MICROVM_CLOSURE/sw/bin
|
|
||||||
cp /etc/resolv.conf /run/
|
|
||||||
$MICROVM_CLOSURE/activate || true
|
|
||||||
mount --bind /run/resolv.conf /etc/resolv.conf
|
|
||||||
mount --bind /run/machine-id /etc/machine-id
|
|
||||||
chown 1337:1337 /run
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Configure user account
|
|
||||||
users.mutableUsers = false;
|
|
||||||
users.users.appvm = {
|
|
||||||
uid = 1337;
|
|
||||||
group = "appvm";
|
|
||||||
isNormalUser = false;
|
|
||||||
isSystemUser = true;
|
|
||||||
home = "/home/appvm";
|
|
||||||
description = "microVM User";
|
|
||||||
extraGroups = [ "wheel" "video" "input" "systemd-journal" ];
|
|
||||||
};
|
|
||||||
users.groups.appvm.gid = 1337;
|
|
||||||
users.allowNoPasswordLogin = true;
|
|
||||||
systemd.tmpfiles.rules = ["d ${runtimeDir} 1337 1337 -"];
|
|
||||||
|
|
||||||
# Configure services
|
|
||||||
|
|
||||||
systemd.services.muvm-remote = {
|
|
||||||
enable = true;
|
|
||||||
description = "microVM Application runner";
|
|
||||||
onFailure = ["exit.target"];
|
|
||||||
onSuccess = ["exit.target"];
|
|
||||||
after = ["microvm-nixos-activation.service"];
|
|
||||||
wantedBy = ["microvm.target"];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "exec";
|
|
||||||
PassEnvironment = ["TERM" "MUVM_REMOTE_CONFIG"]; # "KRUN_CONFIG"];
|
|
||||||
Environment = ["XDG_RUNTIME_DIR=${runtimeDir}" "WAYLAND_DISPLAY=wayland-1" "PATH=/run/current-system/sw/bin"];
|
|
||||||
User = "appvm";
|
|
||||||
Group = "appvm";
|
|
||||||
ExecStart = "/opt/bin/muvm-remote";
|
|
||||||
ExecStopPost = ''+${pkgs.python3}/bin/python -c "import os,fcntl,struct;print(os.getenv('EXIT_STATUS', '1'));fcntl.ioctl(os.open('/', os.O_RDONLY), 0x7602, int(os.getenv('EXIT_STATUS', '1')))"'';
|
|
||||||
} // useTTY;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.muvm-configure-network = {
|
|
||||||
enable = true;
|
|
||||||
description = "microVM Network configuration";
|
|
||||||
wantedBy = ["microvm.target"];
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
serviceConfig.ExecStart = "/opt/bin/muvm-configure-network";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.sockets.muvm-pwbridge = {
|
|
||||||
enable = true;
|
|
||||||
description = "PipeWire cross-domain proxy socket";
|
|
||||||
wantedBy = ["microvm.target"];
|
|
||||||
partOf = ["muvm-pwbridge.service"];
|
|
||||||
listenStreams = [ "${runtimeDir}/pipewire-0" ];
|
|
||||||
socketConfig = {
|
|
||||||
SocketUser = "appvm";
|
|
||||||
SocketGroup = "appvm";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
systemd.services.muvm-pwbridge = {
|
|
||||||
enable = true;
|
|
||||||
description = "PipeWire cross-domain proxy";
|
|
||||||
requires = ["muvm-pwbridge.socket"];
|
|
||||||
serviceConfig.Type = "exec";
|
|
||||||
serviceConfig.ExecStart = "/opt/bin/muvm-pwbridge";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.wait-for-udev = {
|
|
||||||
enable = true;
|
|
||||||
description = "Wait for device rules being applied";
|
|
||||||
wantedBy = ["microvm.target"];
|
|
||||||
requires = ["systemd-udevd.service"];
|
|
||||||
after = ["systemd-udevd.service"];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStart = [
|
|
||||||
"udevadm trigger --action=add"
|
|
||||||
"udevadm settle"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
systemd.sockets.wayland-proxy-virtwl = {
|
|
||||||
enable = true;
|
|
||||||
description = "Wayland cross-domain proxy socket";
|
|
||||||
wantedBy = ["microvm.target"];
|
|
||||||
partOf = ["wayland-proxy-virtwl.service"];
|
|
||||||
listenStreams = [ "${runtimeDir}/wayland-1" ];
|
|
||||||
socketConfig = {
|
|
||||||
SocketUser = "appvm";
|
|
||||||
SocketGroup = "appvm";
|
|
||||||
FileDescriptorName = "wayland";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
systemd.services.wayland-proxy-virtwl = {
|
|
||||||
enable = true;
|
|
||||||
description = "Wayland cross-domain proxy";
|
|
||||||
after = ["wait-for-udev.service"];
|
|
||||||
requires = ["wayland-proxy-virtwl.socket" "wait-for-udev.service"];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${virtwl.packages.x86_64-linux.proxy}/bin/wayland-proxy-virtwl --virtio-gpu";
|
|
||||||
Environment = ["XDG_RUNTIME_DIR=${runtimeDir}"];
|
|
||||||
User = "appvm";
|
|
||||||
Group = "appvm";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.graphics.enable = true;
|
|
||||||
hardware.graphics.package = self.packages.${pkgs.system}.mesa;
|
|
||||||
};
|
|
||||||
|
|
||||||
nixosConfigurations.testvm-x86_64 = nixpkgs.lib.nixosSystem {
|
nixosConfigurations.testvm-x86_64 = nixpkgs.lib.nixosSystem {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
|
|
@ -287,91 +47,29 @@
|
||||||
nixos-testvm = self.nixosConfigurations.testvm-aarch64.config.system.build.toplevel;
|
nixos-testvm = self.nixosConfigurations.testvm-aarch64.config.system.build.toplevel;
|
||||||
});
|
});
|
||||||
|
|
||||||
# packages.libkrunfw = pkgs.libkrunfw;
|
packages = {
|
||||||
packages.libkrunfw = pkgs.libkrunfw.overrideAttrs (old: {
|
# Packages support variant parameter: null (default), "sev", or "tdx"
|
||||||
version = "5.0.0";
|
# To build a variant: packages.libkrunfw.override { variant = "sev"; }
|
||||||
src = ./libkrunfw;
|
libkrunfw = pkgs.callPackage ./packages/libkrunfw { };
|
||||||
# src = pkgs.fetchFromGitHub {
|
|
||||||
# owner = "containers";
|
|
||||||
# repo = "libkrunfw";
|
|
||||||
# tag = "v4.10.0";
|
|
||||||
# hash = "sha256-mq2gw0+xL6qUZE/fk0vLT3PEpzPV8p+iwRFJHXVOMnk=";
|
|
||||||
# };
|
|
||||||
kernelSrc = pkgs.fetchurl {
|
|
||||||
url = "mirror://kernel/linux/kernel/v6.x/linux-6.12.44.tar.xz";
|
|
||||||
hash = "sha256-tlAhDtMCeyJJadFIqjd0Uqmq065/KFGr7dMa3+8Wva4=";
|
|
||||||
};
|
|
||||||
# buildInputs = old.buildInputs;
|
|
||||||
});
|
|
||||||
|
|
||||||
packages.libkrun = (pkgs.libkrun.override {
|
libkrun = pkgs.callPackage ./packages/libkrun {
|
||||||
withBlk = true;
|
|
||||||
withGpu = true;
|
|
||||||
withSound = true;
|
|
||||||
withNet = true;
|
|
||||||
libkrunfw = self.packages.${system}.libkrunfw;
|
libkrunfw = self.packages.${system}.libkrunfw;
|
||||||
}).overrideAttrs (old: {
|
|
||||||
src = ./libkrun;
|
|
||||||
cargoDeps = pkgs.rustPlatform.importCargoLock {
|
|
||||||
lockFile = ./libkrun/Cargo.lock;
|
|
||||||
};
|
};
|
||||||
# mesonFlags = [ (pkgs.lib.mesonOption "decoders" "gles,vulkan,composer") ]; # no magma(?)
|
|
||||||
});
|
|
||||||
|
|
||||||
packages.muvm = (pkgs.muvm.override {
|
mesa = pkgs.callPackage ./packages/mesa { };
|
||||||
|
|
||||||
|
muvm = pkgs.callPackage ./packages/muvm {
|
||||||
libkrun = self.packages.${system}.libkrun;
|
libkrun = self.packages.${system}.libkrun;
|
||||||
}).overrideAttrs (old: {
|
|
||||||
postPatch = ""; # no more sysctl; udevd now takes the var anyway; XXX: fex
|
|
||||||
MUVM_UDEVD_PATH = "${pkgs.systemd}/lib/systemd/systemd-udevd";
|
|
||||||
src = ./muvm;
|
|
||||||
cargoDeps = pkgs.rustPlatform.importCargoLock {
|
|
||||||
lockFile = ./muvm/Cargo.lock;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
packages.munix = let
|
|
||||||
munixScript = (pkgs.writeScriptBin "munix" (builtins.readFile ./munix)).overrideAttrs(old: {
|
|
||||||
buildCommand = "${old.buildCommand}\n patchShebangs $out";
|
|
||||||
});
|
|
||||||
in pkgs.symlinkJoin {
|
|
||||||
name = "munix";
|
|
||||||
paths = [ munixScript self.packages.${system}.muvm pkgs.passt pkgs.bubblewrap ];
|
|
||||||
buildInputs = [ pkgs.makeWrapper ];
|
|
||||||
postBuild = ''
|
|
||||||
wrapProgram $out/bin/munix --prefix PATH : $out/bin
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
devShells.default = let
|
munix = pkgs.callPackage ./packages/munix {
|
||||||
projects = with self.packages.${system}; [ libkrun muvm ];
|
muvm = self.packages.${system}.muvm;
|
||||||
in pkgs.mkShell {
|
};
|
||||||
MUVM_UDEVD_PATH = "${pkgs.systemd}/lib/systemd/systemd-udevd";
|
|
||||||
nativeBuildInputs = pkgs.lib.concatMap (pkg: pkg.nativeBuildInputs) projects;
|
|
||||||
buildInputs = (pkgs.lib.concatMap (pkg: pkg.buildInputs) projects) ++ (with self.packages.${system}; [
|
|
||||||
# virglrenderer
|
|
||||||
]) ++ (with pkgs; [
|
|
||||||
cargo
|
|
||||||
rust-analyzer
|
|
||||||
rustfmt
|
|
||||||
passt
|
|
||||||
bubblewrap
|
|
||||||
]);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.mesa = (pkgs.mesa.override {
|
devShells.default = pkgs.callPackage ./devShells {
|
||||||
vulkanDrivers = [
|
libkrun = self.packages.${system}.libkrun;
|
||||||
"amd"
|
muvm = self.packages.${system}.muvm;
|
||||||
"intel"
|
};
|
||||||
"microsoft-experimental" # removing this breaks the build
|
|
||||||
"nouveau"
|
|
||||||
"swrast"
|
|
||||||
"virtio"
|
|
||||||
"gfxstream" # probably not going to use this though
|
|
||||||
];
|
|
||||||
}).overrideAttrs (new: old: {
|
|
||||||
mesonFlags = old.mesonFlags ++ [ (pkgs.lib.mesonBool "amdgpu-virtio" true) ];
|
|
||||||
patches = old.patches ++ [ ./radvmmio.patch ]; # already merged to git
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
209
nixosModules/default.nix
Normal file
209
nixosModules/default.nix
Normal file
|
|
@ -0,0 +1,209 @@
|
||||||
|
{ self, virtwl }:
|
||||||
|
{ pkgs, lib, utils, config, ... }: let
|
||||||
|
useTTY = {
|
||||||
|
TTYPath = "/dev/hvc0";
|
||||||
|
StandardOutput = "tty";
|
||||||
|
StandardInput = "tty";
|
||||||
|
StandardError = "tty";
|
||||||
|
};
|
||||||
|
runtimeDir = "/run/vm-user";
|
||||||
|
in {
|
||||||
|
boot.isContainer = true;
|
||||||
|
fileSystems."/".device = lib.mkDefault "/dev/sda"; # dummy
|
||||||
|
|
||||||
|
# Disable unused things
|
||||||
|
environment.defaultPackages = lib.mkDefault [ ];
|
||||||
|
documentation = {
|
||||||
|
enable = lib.mkDefault false;
|
||||||
|
doc.enable = lib.mkDefault false;
|
||||||
|
info.enable = lib.mkDefault false;
|
||||||
|
man.enable = lib.mkDefault false;
|
||||||
|
nixos.enable = lib.mkDefault false;
|
||||||
|
};
|
||||||
|
services.logrotate.enable = false;
|
||||||
|
services.udisks2.enable = false;
|
||||||
|
system.tools.nixos-generate-config.enable = false;
|
||||||
|
system.activationScripts.specialfs = lib.mkForce "";
|
||||||
|
systemd.coredump.enable = false;
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
powerManagement.enable = false;
|
||||||
|
boot.kexec.enable = false;
|
||||||
|
console.enable = false;
|
||||||
|
|
||||||
|
# Configure activation / systemd
|
||||||
|
boot.initrd.systemd.enable = true; # for etc.overlay, but we don't have initrd
|
||||||
|
system.etc.overlay.enable = true; # erofs
|
||||||
|
system.etc.overlay.mutable = false;
|
||||||
|
systemd.sysusers.enable = true;
|
||||||
|
services.userborn.enable = false;
|
||||||
|
services.udev.enable = lib.mkDefault true;
|
||||||
|
services.udev.packages = lib.mkDefault [];
|
||||||
|
environment.etc."resolv.conf".text = "# to be overridden with mount";
|
||||||
|
environment.etc."machine-id".text = "# to be overridden with mount";
|
||||||
|
environment.etc."systemd/system".source = lib.mkForce (utils.systemdUtils.lib.generateUnits {
|
||||||
|
type = "system";
|
||||||
|
units = config.systemd.units;
|
||||||
|
upstreamUnits = [
|
||||||
|
"sysinit.target"
|
||||||
|
"local-fs.target"
|
||||||
|
"nss-user-lookup.target"
|
||||||
|
"umount.target"
|
||||||
|
"shutdown.target"
|
||||||
|
"reboot.target"
|
||||||
|
"exit.target"
|
||||||
|
"final.target"
|
||||||
|
"systemd-exit.service"
|
||||||
|
"systemd-journald.socket"
|
||||||
|
"systemd-journald-audit.socket"
|
||||||
|
"systemd-journald-dev-log.socket"
|
||||||
|
"systemd-journald.service"
|
||||||
|
"systemd-sysusers.service"
|
||||||
|
"systemd-udevd-kernel.socket"
|
||||||
|
"systemd-udevd-control.socket"
|
||||||
|
"systemd-udevd.service"
|
||||||
|
"systemd-tmpfiles-setup.service"
|
||||||
|
"user.slice"
|
||||||
|
];
|
||||||
|
upstreamWants = ["multi-user.target.wants"];
|
||||||
|
});
|
||||||
|
|
||||||
|
# systemd.package = pkgs.systemdMinimal; # no sysusers
|
||||||
|
systemd.defaultUnit = "microvm.target";
|
||||||
|
systemd.targets.microvm = {
|
||||||
|
description = "Minimal microVM system";
|
||||||
|
wants = ["systemd-journald.socket" "systemd-udevd.service" "dbus.socket"];
|
||||||
|
unitConfig.AllowIsolate = "yes";
|
||||||
|
};
|
||||||
|
systemd.services.systemd-remount-fs.enable = lib.mkForce false;
|
||||||
|
systemd.services.systemd-pstore.enable = lib.mkForce false;
|
||||||
|
systemd.services.lastlog2-import.enable = lib.mkForce false;
|
||||||
|
systemd.services.suid-sgid-wrappers.enable = lib.mkForce false;
|
||||||
|
systemd.services.systemd-sysusers.serviceConfig = {
|
||||||
|
ExecStartPre = lib.mkForce [];
|
||||||
|
ExecStartPost = lib.mkForce [];
|
||||||
|
};
|
||||||
|
systemd.services.microvm-nixos-activation = {
|
||||||
|
enable = true;
|
||||||
|
description = "NixOS Activation";
|
||||||
|
wantedBy = ["local-fs.target"];
|
||||||
|
before = ["systemd-tmpfiles-setup.service" "systemd-sysusers.service"];
|
||||||
|
requires = ["systemd-tmpfiles-setup.service" "systemd-sysusers.service"];
|
||||||
|
unitConfig.DefaultDependencies = false;
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
PassEnvironment = ["MICROVM_CLOSURE" "MICROVM_UID" "MICROVM_GID"];
|
||||||
|
} // useTTY;
|
||||||
|
script = ''
|
||||||
|
PATH=$MICROVM_CLOSURE/sw/bin
|
||||||
|
cp /etc/resolv.conf /run/
|
||||||
|
$MICROVM_CLOSURE/activate || true
|
||||||
|
mount --bind /run/resolv.conf /etc/resolv.conf
|
||||||
|
mount --bind /run/machine-id /etc/machine-id
|
||||||
|
chown 1337:1337 /run
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure user account
|
||||||
|
users.mutableUsers = false;
|
||||||
|
users.users.appvm = {
|
||||||
|
uid = 1337;
|
||||||
|
group = "appvm";
|
||||||
|
isNormalUser = false;
|
||||||
|
isSystemUser = true;
|
||||||
|
home = "/home/appvm";
|
||||||
|
description = "microVM User";
|
||||||
|
extraGroups = [ "wheel" "video" "input" "systemd-journal" ];
|
||||||
|
};
|
||||||
|
users.groups.appvm.gid = 1337;
|
||||||
|
users.allowNoPasswordLogin = true;
|
||||||
|
systemd.tmpfiles.rules = ["d ${runtimeDir} 1337 1337 -"];
|
||||||
|
|
||||||
|
# Configure services
|
||||||
|
|
||||||
|
systemd.services.muvm-remote = {
|
||||||
|
enable = true;
|
||||||
|
description = "microVM Application runner";
|
||||||
|
onFailure = ["exit.target"];
|
||||||
|
onSuccess = ["exit.target"];
|
||||||
|
after = ["microvm-nixos-activation.service"];
|
||||||
|
wantedBy = ["microvm.target"];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "exec";
|
||||||
|
PassEnvironment = ["TERM" "MUVM_REMOTE_CONFIG"]; # "KRUN_CONFIG"];
|
||||||
|
Environment = ["XDG_RUNTIME_DIR=${runtimeDir}" "WAYLAND_DISPLAY=wayland-1" "PATH=/run/current-system/sw/bin"];
|
||||||
|
User = "appvm";
|
||||||
|
Group = "appvm";
|
||||||
|
ExecStart = "/opt/bin/muvm-remote";
|
||||||
|
ExecStopPost = ''+${pkgs.python3}/bin/python -c "import os,fcntl,struct;print(os.getenv('EXIT_STATUS', '1'));fcntl.ioctl(os.open('/', os.O_RDONLY), 0x7602, int(os.getenv('EXIT_STATUS', '1')))"'';
|
||||||
|
} // useTTY;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.muvm-configure-network = {
|
||||||
|
enable = true;
|
||||||
|
description = "microVM Network configuration";
|
||||||
|
wantedBy = ["microvm.target"];
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
serviceConfig.ExecStart = "/opt/bin/muvm-configure-network";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.sockets.muvm-pwbridge = {
|
||||||
|
enable = true;
|
||||||
|
description = "PipeWire cross-domain proxy socket";
|
||||||
|
wantedBy = ["microvm.target"];
|
||||||
|
partOf = ["muvm-pwbridge.service"];
|
||||||
|
listenStreams = [ "${runtimeDir}/pipewire-0" ];
|
||||||
|
socketConfig = {
|
||||||
|
SocketUser = "appvm";
|
||||||
|
SocketGroup = "appvm";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.muvm-pwbridge = {
|
||||||
|
enable = true;
|
||||||
|
description = "PipeWire cross-domain proxy";
|
||||||
|
requires = ["muvm-pwbridge.socket"];
|
||||||
|
serviceConfig.Type = "exec";
|
||||||
|
serviceConfig.ExecStart = "/opt/bin/muvm-pwbridge";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.wait-for-udev = {
|
||||||
|
enable = true;
|
||||||
|
description = "Wait for device rules being applied";
|
||||||
|
wantedBy = ["microvm.target"];
|
||||||
|
requires = ["systemd-udevd.service"];
|
||||||
|
after = ["systemd-udevd.service"];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = [
|
||||||
|
"udevadm trigger --action=add"
|
||||||
|
"udevadm settle"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.sockets.wayland-proxy-virtwl = {
|
||||||
|
enable = true;
|
||||||
|
description = "Wayland cross-domain proxy socket";
|
||||||
|
wantedBy = ["microvm.target"];
|
||||||
|
partOf = ["wayland-proxy-virtwl.service"];
|
||||||
|
listenStreams = [ "${runtimeDir}/wayland-1" ];
|
||||||
|
socketConfig = {
|
||||||
|
SocketUser = "appvm";
|
||||||
|
SocketGroup = "appvm";
|
||||||
|
FileDescriptorName = "wayland";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.wayland-proxy-virtwl = {
|
||||||
|
enable = true;
|
||||||
|
description = "Wayland cross-domain proxy";
|
||||||
|
after = ["wait-for-udev.service"];
|
||||||
|
requires = ["wayland-proxy-virtwl.socket" "wait-for-udev.service"];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${virtwl.packages.x86_64-linux.proxy}/bin/wayland-proxy-virtwl --virtio-gpu";
|
||||||
|
Environment = ["XDG_RUNTIME_DIR=${runtimeDir}"];
|
||||||
|
User = "appvm";
|
||||||
|
Group = "appvm";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.graphics.enable = true;
|
||||||
|
hardware.graphics.package = self.packages.${pkgs.system}.mesa;
|
||||||
|
}
|
||||||
34
nixosModules/testvm.nix
Normal file
34
nixosModules/testvm.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
{ virtwl }:
|
||||||
|
{ pkgs, ... }: {
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
|
||||||
|
fonts.packages = [ pkgs.adwaita-fonts pkgs.dejavu_fonts ];
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.fastfetch
|
||||||
|
pkgs.htop
|
||||||
|
virtwl.packages.${pkgs.system}.proxy
|
||||||
|
pkgs.wayland-utils
|
||||||
|
pkgs.weston
|
||||||
|
pkgs.waycheck
|
||||||
|
pkgs.vulkan-tools
|
||||||
|
pkgs.glmark2
|
||||||
|
pkgs.mesa-demos
|
||||||
|
pkgs.xorg.xeyes
|
||||||
|
pkgs.xterm
|
||||||
|
# pkgs.vkquake # build broken: Program 'spirv-remap' not found
|
||||||
|
pkgs.veloren
|
||||||
|
pkgs.kdePackages.kate
|
||||||
|
pkgs.adwaita-icon-theme
|
||||||
|
pkgs.amberol
|
||||||
|
pkgs.bustle
|
||||||
|
pkgs.d-spy
|
||||||
|
pkgs.gnome-text-editor
|
||||||
|
pkgs.firefox
|
||||||
|
pkgs.ffmpeg-full
|
||||||
|
pkgs.mpv
|
||||||
|
pkgs.libva-utils
|
||||||
|
pkgs.tailscale
|
||||||
|
pkgs.zerotierone
|
||||||
|
pkgs.localsend
|
||||||
|
];
|
||||||
|
}
|
||||||
19
packages/libkrun/default.nix
Normal file
19
packages/libkrun/default.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{ libkrun, libkrunfw, rustPlatform, variant ? null, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
libkrunfw' = libkrunfw.override { inherit variant; };
|
||||||
|
in
|
||||||
|
(libkrun.override {
|
||||||
|
withBlk = true;
|
||||||
|
withGpu = true;
|
||||||
|
withSound = true;
|
||||||
|
withNet = true;
|
||||||
|
inherit variant;
|
||||||
|
libkrunfw = libkrunfw';
|
||||||
|
}).overrideAttrs (old: {
|
||||||
|
src = ../../libkrun;
|
||||||
|
cargoDeps = rustPlatform.importCargoLock {
|
||||||
|
lockFile = ../../libkrun/Cargo.lock;
|
||||||
|
};
|
||||||
|
# mesonFlags = [ (lib.mesonOption "decoders" "gles,vulkan,composer") ]; # no magma(?)
|
||||||
|
})
|
||||||
19
packages/libkrunfw/default.nix
Normal file
19
packages/libkrunfw/default.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{ libkrunfw, fetchurl, variant ? null, ... }:
|
||||||
|
|
||||||
|
(libkrunfw.override {
|
||||||
|
inherit variant;
|
||||||
|
}).overrideAttrs (old: {
|
||||||
|
version = "5.0.0";
|
||||||
|
src = ../../libkrunfw;
|
||||||
|
# src = fetchFromGitHub {
|
||||||
|
# owner = "containers";
|
||||||
|
# repo = "libkrunfw";
|
||||||
|
# tag = "v4.10.0";
|
||||||
|
# hash = "sha256-mq2gw0+xL6qUZE/fk0vLT3PEpzPV8p+iwRFJHXVOMnk=";
|
||||||
|
# };
|
||||||
|
kernelSrc = fetchurl {
|
||||||
|
url = "mirror://kernel/linux/kernel/v6.x/linux-6.12.44.tar.xz";
|
||||||
|
hash = "sha256-tlAhDtMCeyJJadFIqjd0Uqmq065/KFGr7dMa3+8Wva4=";
|
||||||
|
};
|
||||||
|
# buildInputs = old.buildInputs;
|
||||||
|
})
|
||||||
16
packages/mesa/default.nix
Normal file
16
packages/mesa/default.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{ mesa, lib }:
|
||||||
|
|
||||||
|
(mesa.override {
|
||||||
|
vulkanDrivers = [
|
||||||
|
"amd"
|
||||||
|
"intel"
|
||||||
|
"microsoft-experimental" # removing this breaks the build
|
||||||
|
"nouveau"
|
||||||
|
"swrast"
|
||||||
|
"virtio"
|
||||||
|
"gfxstream" # probably not going to use this though
|
||||||
|
];
|
||||||
|
}).overrideAttrs (new: old: {
|
||||||
|
mesonFlags = old.mesonFlags ++ [ (lib.mesonBool "amdgpu-virtio" true) ];
|
||||||
|
patches = old.patches ++ [ ../../radvmmio.patch ]; # already merged to git
|
||||||
|
})
|
||||||
14
packages/munix/default.nix
Normal file
14
packages/munix/default.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{ writeScriptBin, symlinkJoin, makeWrapper, muvm, passt, bubblewrap }:
|
||||||
|
|
||||||
|
let
|
||||||
|
munixScript = (writeScriptBin "munix" (builtins.readFile ../../munix)).overrideAttrs(old: {
|
||||||
|
buildCommand = "${old.buildCommand}\n patchShebangs $out";
|
||||||
|
});
|
||||||
|
in symlinkJoin {
|
||||||
|
name = "munix";
|
||||||
|
paths = [ munixScript muvm passt bubblewrap ];
|
||||||
|
buildInputs = [ makeWrapper ];
|
||||||
|
postBuild = ''
|
||||||
|
wrapProgram $out/bin/munix --prefix PATH : $out/bin
|
||||||
|
'';
|
||||||
|
}
|
||||||
12
packages/muvm/default.nix
Normal file
12
packages/muvm/default.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ muvm, libkrun, systemd, rustPlatform }:
|
||||||
|
|
||||||
|
(muvm.override {
|
||||||
|
libkrun = libkrun;
|
||||||
|
}).overrideAttrs (old: {
|
||||||
|
postPatch = ""; # no more sysctl; udevd now takes the var anyway; XXX: fex
|
||||||
|
MUVM_UDEVD_PATH = "${systemd}/lib/systemd/systemd-udevd";
|
||||||
|
src = ../../muvm;
|
||||||
|
cargoDeps = rustPlatform.importCargoLock {
|
||||||
|
lockFile = ../../muvm/Cargo.lock;
|
||||||
|
};
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue