]> git.scottworley.com Git - nixos-qemu-vm-isolation/blame - modules/qemu-vm-isolation.nix
Offer option of an erofs nix store image
[nixos-qemu-vm-isolation] / modules / qemu-vm-isolation.nix
CommitLineData
69619e0b
SW
1{ config, lib, modulesPath, pkgs, ... }:
2let
f78c24af
SW
3 inherit (lib)
4 escapeShellArg findSingle mkForce mkIf mkMerge mkOption mkVMOverride
5 optional;
6
7 cfg = config.virtualisation.qemu.isolation;
69619e0b
SW
8
9 lookupDriveDeviceName = driveName: driveList:
10 (findSingle (drive: drive.name == driveName)
11 (throw "Drive ${driveName} not found")
12 (throw "Multiple drives named ${driveName}") driveList).device;
13
14 storeMountPath = if config.virtualisation.writableStore then
15 "/nix/.ro-store"
16 else
17 "/nix/store";
18
f78c24af 19 hostPkgs = config.virtualisation.host.pkgs;
69619e0b 20
f78c24af
SW
21 storeContents =
22 hostPkgs.closureInfo { rootPaths = config.virtualisation.additionalPaths; };
68bdafb0 23
f78c24af
SW
24 nixStoreImages = {
25 ext4 = import (modulesPath + "/../lib/make-disk-image.nix") {
68bdafb0 26 inherit pkgs config lib;
f78c24af 27 additionalPaths = [ storeContents ];
68bdafb0
SW
28 onlyNixStore = true;
29 label = "nix-store";
30 partitionTableType = "none";
31 installBootLoader = false;
32 diskSize = "auto";
33 additionalSpace = "0M";
34 copyChannel = false;
26efd1b6 35 };
f78c24af
SW
36 erofs = hostPkgs.runCommand "nix-store-image" { } ''
37 mkdir $out
38 cd ${builtins.storeDir}
39 ${hostPkgs.erofs-utils}/bin/mkfs.erofs \
40 --force-uid=0 \
41 --force-gid=0 \
42 -L nix-store \
43 -U eb176051-bd15-49b7-9e6b-462e0b467019 \
44 -T 0 \
45 --exclude-regex="$(
46 <${storeContents}/store-paths \
47 sed -e 's^.*/^^g' \
48 | cut -c -10 \
49 | ${hostPkgs.python3}/bin/python -c ${
50 escapeShellArg (builtins.readFile
51 (modulesPath + "/virtualisation/includes-to-excludes.py"))
52 } )" \
53 $out/nixos.img \
54 .
55 '';
56 };
69619e0b 57
f78c24af
SW
58in {
59 options = {
60 virtualisation.qemu.isolation.nixStoreFilesystemType = mkOption {
61 description = ''
62 What filesystem to use for the guest's Nix store.
69619e0b 63
f78c24af
SW
64 erofs is more compact than ext4, but less mature.
65 '';
66 type = lib.types.enum [ "ext4" "erofs" ];
67 default = "ext4";
68 };
69 };
70 config = mkMerge [
71 {
72 boot.initrd.kernelModules =
73 optional (cfg.nixStoreFilesystemType == "erofs") "erofs";
69619e0b 74
f78c24af
SW
75 fileSystems = mkVMOverride {
76 "${storeMountPath}" = {
77 device =
78 lookupDriveDeviceName "nixstore" config.virtualisation.qemu.drives;
79 fsType = cfg.nixStoreFilesystemType;
80 options = [ "ro" ];
81 neededForBoot = true;
82 };
26efd1b6 83 };
69619e0b 84
f78c24af
SW
85 system.build.nixStoreImage =
86 nixStoreImages."${cfg.nixStoreFilesystemType}";
87
88 virtualisation = {
89
90 sharedDirectories = mkForce { };
91
92 qemu.drives = [{
93 name = "nixstore";
94 file = "${config.system.build.nixStoreImage}/nixos.img";
95 driveExtraOpts = {
96 format = "raw";
97 read-only = "on";
98 werror = "report";
99 };
100 }];
101
102 };
103 }
104 (mkIf (cfg.nixStoreFilesystemType == "ext4") {
105 # We use this to disable fsck runs on the ext4 nix store image because stage-1
106 # fsck crashes (maybe because the device is read-only?), halting boot.
107 boot.initrd.checkJournalingFS = false;
108 })
109 ];
26efd1b6 110}