]> git.scottworley.com Git - nixos-qemu-vm-isolation/blob - modules/qemu-vm-isolation.nix
Put squashfs-label patch overlays in a separate file
[nixos-qemu-vm-isolation] / modules / qemu-vm-isolation.nix
1 { config, lib, modulesPath, pkgs, ... }:
2 let
3 inherit (lib)
4 escapeShellArg mkForce mkIf mkMerge mkOption mkVMOverride optional;
5
6 cfg = config.virtualisation.qemu.isolation;
7
8 storeMountPath = if config.virtualisation.writableStore then
9 "/nix/.ro-store"
10 else
11 "/nix/store";
12
13 hostPkgs = config.virtualisation.host.pkgs;
14
15 storeContents =
16 hostPkgs.closureInfo { rootPaths = config.virtualisation.additionalPaths; };
17
18 nixStoreImages = {
19 ext4 = "${
20 import (modulesPath + "/../lib/make-disk-image.nix") {
21 inherit pkgs config lib;
22 additionalPaths = [ storeContents ];
23 onlyNixStore = true;
24 label = "nix-store";
25 partitionTableType = "none";
26 installBootLoader = false;
27 diskSize = "auto";
28 additionalSpace = "0M";
29 copyChannel = false;
30 }
31 }/nixos.img";
32 erofs = "${
33 hostPkgs.runCommand "nix-store-image" { } ''
34 mkdir $out
35 ${hostPkgs.gnutar}/bin/tar --create \
36 --absolute-names \
37 --verbatim-files-from \
38 --transform 'flags=rSh;s|/nix/store/||' \
39 --files-from ${storeContents}/store-paths \
40 | ${hostPkgs.erofs-utils}/bin/mkfs.erofs \
41 --force-uid=0 \
42 --force-gid=0 \
43 -L nix-store \
44 -U eb176051-bd15-49b7-9e6b-462e0b467019 \
45 -T 0 \
46 --tar=f \
47 $out/nix-store.img
48 ''
49 }/nix-store.img";
50 squashfs =
51 "${hostPkgs.callPackage (modulesPath + "/../lib/make-squashfs.nix") {
52 squashfsTools =
53 (hostPkgs.extend (import ../overlays/squashfs-labels)).squashfsTools.overrideAttrs
54 (old: {
55 buildInputs = (old.buildInputs or [ ]) ++ [ hostPkgs.makeWrapper ];
56 postInstall = (old.postInstall or "") + ''
57 wrapProgram "$out/bin/mksquashfs" \
58 --append-flags "-label nix-store"
59 '';
60 });
61 storeContents = config.virtualisation.additionalPaths;
62 }}";
63 };
64
65 in {
66 options = {
67 virtualisation.qemu.isolation.nixStoreFilesystemType = mkOption {
68 description = ''
69 What filesystem to use for the guest's Nix store.
70
71 erofs is more compact than ext4, but less mature.
72
73 squashfs is best, but requires patches to set the filesystem label.
74 '';
75 type = lib.types.enum [ "ext4" "erofs" "squashfs" ];
76 default = "ext4";
77 };
78 };
79 config = mkMerge [
80 {
81 boot.initrd.kernelModules =
82 optional (cfg.nixStoreFilesystemType == "erofs") "erofs";
83
84 nixpkgs.overlays = optional (cfg.nixStoreFilesystemType == "squashfs")
85 (import ../overlays/squashfs-labels);
86
87 fileSystems = mkVMOverride {
88 "${storeMountPath}" = {
89 fsType = cfg.nixStoreFilesystemType;
90 options = [ "ro" ];
91 neededForBoot = true;
92 label = "nix-store";
93 };
94 };
95
96 system.build.nixStoreImage =
97 nixStoreImages."${cfg.nixStoreFilesystemType}";
98
99 virtualisation = {
100
101 sharedDirectories = mkForce { };
102
103 qemu.drives = [{
104 file = config.system.build.nixStoreImage;
105 driveExtraOpts = {
106 format = "raw";
107 read-only = "on";
108 werror = "report";
109 };
110 }];
111
112 };
113 }
114 (mkIf (cfg.nixStoreFilesystemType == "ext4") {
115 # We use this to disable fsck runs on the ext4 nix store image because stage-1
116 # fsck crashes (maybe because the device is read-only?), halting boot.
117 boot.initrd.checkJournalingFS = false;
118 })
119 ];
120 }