uvms/profiles/ch-runner.nix
Else, Someone 28d3f89ad4 pkgs.writeErofsLayers,profiles/ch-runner: MVE
$ nix-build -A examples.dummy.config.debug.closure.erofs.list | xargs
cat | xargs du -h
749M    /nix/store/bzfv5x6lycq6hzhjv6d6vlk1q8fdg9di-base0.erofs
24M     /nix/store/hp41jfq36y0mmjrzqilyh3jfsvqic3kb-nixos.erofs

$ nix run -f . examples.dummy.config.uvms.cloud-hypervisor.runner
...
<<< Welcome to NixOS 25.11pre-git (x86_64) - ttyS0 >>>

nixos login:

The definition of the `pkgs` fixpoint was moved to pkgs/default.nix.
For that, dirToAttrs was moved to lib/, imported ad hoc
2025-09-21 00:57:11 +03:00

114 lines
3.4 KiB
Nix

{
config,
lib,
pkgs,
...
}:
# It is not the intent to stick to the microvm.nix-like static interface,
# but we shall begin by reproducing at least some of their work.
let
cfg = config.uvms.cloud-hypervisor;
inherit (config.debug.closure.erofs) layers;
in
{
options = {
uvms.cloud-hypervisor.enable = lib.mkEnableOption "Configure guest (e.g. fileSystems)";
uvms.cloud-hypervisor.runner = lib.mkOption {
type = lib.types.package;
description = "A naive script for running this system in cloud-hypervisor";
};
uvms.cloud-hypervisor.extraArgv = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
};
uvms.cloud-hypervisor.argv = lib.mkOption {
type = lib.types.listOf lib.types.str;
};
uvms.cloud-hypervisor.extraCmdline = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
};
uvms.cloud-hypervisor.cmdline = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"earlyprintk=ttyS0"
"console=ttyS0"
"reboot=t"
"panic=-1"
"init=${config.system.build.toplevel}/init"
]
++ config.boot.kernelParams
++ config.uvms.cloud-hypervisor.extraCmdline;
};
};
config = lib.mkMerge [
{
uvms.cloud-hypervisor.argv = lib.mkBefore (
[
(lib.getExe pkgs.cloud-hypervisor)
"--cmdline=${lib.concatStringsSep " " cfg.cmdline}"
"--kernel=${config.boot.kernelPackages.kernel}/${pkgs.stdenv.hostPlatform.linux-kernel.target}"
"--initramfs=${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"
"--vsock=cid=4,socket=CONNECT.sock"
"--api-socket=ch.sock"
"--serial=tty"
"--console=null"
"--watchdog"
"--seccomp=true"
]
++ cfg.extraArgv
);
uvms.cloud-hypervisor.runner = pkgs.writeShellScriptBin "run-${config.networking.hostName}" ''
set -euo pipefail
GUESTNAME=${config.networking.hostName}
args=(
${lib.concatMapStringsSep "\n" lib.escapeShellArg cfg.argv}
)
mkdir -p "$HOME/uvms/$GUESTNAME"
cd "$HOME/uvms/$GUESTNAME"
cleanup() {
rm "$HOME/uvms/$GUESTNAME"/{ch,CONNECT}.sock
}
exec -a "uuvm/$GUESTNAME" "''${args[@]}"
'';
}
(lib.mkIf cfg.enable {
boot.initrd.availableKernelModules = [
"erofs"
"overlay"
"virtio_mmio"
"virtio_pci"
"virtio_blk"
# "9pnet_virtio"
# "9p"
"virtiofs"
];
boot.initrd.systemd.enable = true;
fileSystems = {
"/nix/store" = {
fsType = "overlay";
overlay.lowerdir = map (img: "/nix/.ro-stores/${toString img.seq}") layers;
neededForBoot = true;
};
}
// lib.listToAttrs (
map (
img:
lib.nameValuePair "/nix/.ro-stores/${toString img.seq}" {
device = "/dev/disk/by-label/${img.label}";
neededForBoot = true;
options = [ "x-systemd.device-timeout=5" ];
}
) layers
);
uvms.cloud-hypervisor.argv = [
"--memory=size=1536M,hotplug_size=1536M,hotplugged_size=512M,hotplug_method=virtio-mem,mergeable=on,shared=on"
"--cpus=boot=4"
"--disk"
]
++ map (img: "path=${img},readonly=true,id=${toString img.label}") layers;
})
];
}