diff --git a/checks/mount-grep.nix b/checks/mount-grep.nix index 5354d26..c337b4d 100644 --- a/checks/mount-grep.nix +++ b/checks/mount-grep.nix @@ -12,6 +12,10 @@ pkgs: { imports = [ ../modules/qemu-vm-isolation.nix ]; virtualisation.qemu.isolation.nixStoreFilesystemType = "erofs"; }; + privateSquash = _: { + imports = [ ../modules/qemu-vm-isolation.nix ]; + virtualisation.qemu.isolation.nixStoreFilesystemType = "squashfs"; + }; useNixStoreImage = { virtualisation = { sharedDirectories = pkgs.lib.mkForce { }; @@ -22,13 +26,13 @@ pkgs: { testScript = '' start_all() - for machine in [shared, private, privateErofs, useNixStoreImage]: + for machine in [shared, private, privateErofs, privateSquash, useNixStoreImage]: machine.wait_for_unit("multi-user.target") shared.succeed("[[ $(mount | grep -c virt) -gt 0 ]]") shared.succeed("[[ -e ${pkgs.pv} ]]") - for machine in [private, privateErofs, useNixStoreImage]: + for machine in [private, privateErofs, privateSquash, useNixStoreImage]: machine.succeed("[[ $(mount | grep -c virt) -eq 0 ]]") machine.fail("[[ -e ${pkgs.pv} ]]") ''; diff --git a/modules/libblkid-squashfs-nix-store-kludge.patch b/modules/libblkid-squashfs-nix-store-kludge.patch new file mode 100644 index 0000000..de971f7 --- /dev/null +++ b/modules/libblkid-squashfs-nix-store-kludge.patch @@ -0,0 +1,19 @@ +# This dubious kludge results from +# https://github.com/NixOS/nixpkgs/pull/236656 requiring filesystems to have labels and +# https://github.com/plougher/squashfs-tools/issues/59 squashfs not supporting labels. +diff --git a/libblkid/src/superblocks/squashfs.c b/libblkid/src/superblocks/squashfs.c +index 4db842493..ed7465882 100644 +--- a/libblkid/src/superblocks/squashfs.c ++++ b/libblkid/src/superblocks/squashfs.c +@@ -45,6 +45,11 @@ static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag) + + blkid_probe_sprintf_version(pr, "%u.%u", vermaj, vermin); + ++ { ++ char label_kludge[] = "nix-store"; ++ blkid_probe_set_label(pr, label_kludge, sizeof(label_kludge)); ++ } ++ + return 0; + } + diff --git a/modules/qemu-vm-isolation.nix b/modules/qemu-vm-isolation.nix index bea4174..a7189e5 100644 --- a/modules/qemu-vm-isolation.nix +++ b/modules/qemu-vm-isolation.nix @@ -16,37 +16,45 @@ let hostPkgs.closureInfo { rootPaths = config.virtualisation.additionalPaths; }; nixStoreImages = { - ext4 = import (modulesPath + "/../lib/make-disk-image.nix") { - inherit pkgs config lib; - additionalPaths = [ storeContents ]; - onlyNixStore = true; - label = "nix-store"; - partitionTableType = "none"; - installBootLoader = false; - diskSize = "auto"; - additionalSpace = "0M"; - copyChannel = false; - }; - erofs = hostPkgs.runCommand "nix-store-image" { } '' - mkdir $out - cd ${builtins.storeDir} - ${hostPkgs.erofs-utils}/bin/mkfs.erofs \ - --force-uid=0 \ - --force-gid=0 \ - -L nix-store \ - -U eb176051-bd15-49b7-9e6b-462e0b467019 \ - -T 0 \ - --exclude-regex="$( - <${storeContents}/store-paths \ - sed -e 's^.*/^^g' \ - | cut -c -10 \ - | ${hostPkgs.python3}/bin/python -c ${ - escapeShellArg (builtins.readFile - (modulesPath + "/virtualisation/includes-to-excludes.py")) - } )" \ - $out/nixos.img \ - . - ''; + ext4 = "${ + import (modulesPath + "/../lib/make-disk-image.nix") { + inherit pkgs config lib; + additionalPaths = [ storeContents ]; + onlyNixStore = true; + label = "nix-store"; + partitionTableType = "none"; + installBootLoader = false; + diskSize = "auto"; + additionalSpace = "0M"; + copyChannel = false; + } + }/nixos.img"; + erofs = "${ + hostPkgs.runCommand "nix-store-image" { } '' + mkdir $out + cd ${builtins.storeDir} + ${hostPkgs.erofs-utils}/bin/mkfs.erofs \ + --force-uid=0 \ + --force-gid=0 \ + -L nix-store \ + -U eb176051-bd15-49b7-9e6b-462e0b467019 \ + -T 0 \ + --exclude-regex="$( + <${storeContents}/store-paths \ + sed -e 's^.*/^^g' \ + | cut -c -10 \ + | ${hostPkgs.python3}/bin/python -c ${ + escapeShellArg (builtins.readFile + (modulesPath + "/virtualisation/includes-to-excludes.py")) + } )" \ + $out/nix-store.img \ + . + '' + }/nix-store.img"; + squashfs = + "${hostPkgs.callPackage (modulesPath + "/../lib/make-squashfs.nix") { + storeContents = config.virtualisation.additionalPaths; + }}"; }; in { @@ -56,8 +64,11 @@ in { What filesystem to use for the guest's Nix store. erofs is more compact than ext4, but less mature. + + squashfs support currently requires a dubious kludge that results in these + VMs not being able to mount any other squashfs volumes besides the nix store. ''; - type = lib.types.enum [ "ext4" "erofs" ]; + type = lib.types.enum [ "ext4" "erofs" "squashfs" ]; default = "ext4"; }; }; @@ -66,6 +77,14 @@ in { boot.initrd.kernelModules = optional (cfg.nixStoreFilesystemType == "erofs") "erofs"; + nixpkgs.overlays = optional (cfg.nixStoreFilesystemType == "squashfs") + (final: prev: { + util-linux = prev.util-linux.overrideAttrs (old: { + patches = (old.patches or [ ]) + ++ [ ./libblkid-squashfs-nix-store-kludge.patch ]; + }); + }); + fileSystems = mkVMOverride { "${storeMountPath}" = { fsType = cfg.nixStoreFilesystemType; @@ -83,7 +102,7 @@ in { sharedDirectories = mkForce { }; qemu.drives = [{ - file = "${config.system.build.nixStoreImage}/nixos.img"; + file = config.system.build.nixStoreImage; driveExtraOpts = { format = "raw"; read-only = "on";