diff options
| author | lassulus <github@lassul.us> | 2024-07-18 19:34:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-18 19:34:51 +0200 |
| commit | a62c421981c870b686ceeee05d98f5360b1b1625 (patch) | |
| tree | f7db2a8a261e01bebe20a0d139d23942fd8f9954 | |
| parent | Merge pull request #324438 from mweinelt/nss-3.102 (diff) | |
| parent | nixos/qemu-vm: remove creation of /etc/nixos (diff) | |
| download | nixpkgs-a62c421981c870b686ceeee05d98f5360b1b1625.tar.gz | |
Merge pull request #290730 from nikstur/qemu-vm-refactoring
qemu-vm.nix refactoring
| -rw-r--r-- | nixos/modules/virtualisation/qemu-vm.nix | 87 | ||||
| -rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
| -rw-r--r-- | nixos/tests/qemu-vm-store.nix | 71 |
3 files changed, 90 insertions, 69 deletions
diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 428cca4adcf8..3cc20464b00b 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -393,7 +393,7 @@ in The path (inside the VM) to the device containing the EFI System Partition (ESP). If you are *not* booting from a UEFI firmware, this value is, by - default, `null`. The ESP is mounted under `/boot`. + default, `null`. The ESP is mounted to `boot.loader.efi.efiSysMountpoint`. ''; }; @@ -1054,38 +1054,6 @@ in boot.loader.supportsInitrdSecrets = mkIf (!cfg.useBootLoader) (mkVMOverride false); - boot.initrd.postMountCommands = lib.mkIf (!config.boot.initrd.systemd.enable) - '' - # Mark this as a NixOS machine. - mkdir -p $targetRoot/etc - echo -n > $targetRoot/etc/NIXOS - - # Fix the permissions on /tmp. - chmod 1777 $targetRoot/tmp - - mkdir -p $targetRoot/boot - - ${optionalString cfg.writableStore '' - echo "mounting overlay filesystem on /nix/store..." - mkdir -p -m 0755 $targetRoot/nix/.rw-store/store $targetRoot/nix/.rw-store/work $targetRoot/nix/store - mount -t overlay overlay $targetRoot/nix/store \ - -o lowerdir=$targetRoot/nix/.ro-store,upperdir=$targetRoot/nix/.rw-store/store,workdir=$targetRoot/nix/.rw-store/work || fail - ''} - ''; - - systemd.tmpfiles.settings."10-qemu-vm" = lib.mkIf config.boot.initrd.systemd.enable { - "/etc/NIXOS".f = { - mode = "0644"; - user = "root"; - group = "root"; - }; - "${config.boot.loader.efi.efiSysMountPoint}".d = { - mode = "0644"; - user = "root"; - group = "root"; - }; - }; - # After booting, register the closure of the paths in # `virtualisation.additionalPaths' in the Nix database in the VM. This # allows Nix operations to work in the VM. The path to the @@ -1101,8 +1069,7 @@ in ''; boot.initrd.availableKernelModules = - optional cfg.writableStore "overlay" - ++ optional (cfg.qemu.diskInterface == "scsi") "sym53c8xx" + optional (cfg.qemu.diskInterface == "scsi") "sym53c8xx" ++ optional (cfg.tpm.enable) "tpm_tis"; virtualisation.additionalPaths = [ config.system.build.toplevel ]; @@ -1110,7 +1077,9 @@ in virtualisation.sharedDirectories = { nix-store = mkIf cfg.mountHostNixStore { source = builtins.storeDir; - target = "/nix/store"; + # Always mount this to /nix/.ro-store because we never want to actually + # write to the host Nix Store. + target = "/nix/.ro-store"; securityModel = "none"; }; xchg = { @@ -1220,10 +1189,7 @@ in virtualisation.fileSystems = let mkSharedDir = tag: share: { - name = - if tag == "nix-store" && cfg.writableStore - then "/nix/.ro-store" - else share.target; + name = share.target; value.device = tag; value.fsType = "9p"; value.neededForBoot = true; @@ -1248,7 +1214,17 @@ in # Sync with systemd's tmp.mount; options = [ "mode=1777" "strictatime" "nosuid" "nodev" "size=${toString config.boot.tmp.tmpfsSize}" ]; }; - "/nix/${if cfg.writableStore then ".ro-store" else "store"}" = lib.mkIf cfg.useNixStoreImage { + "/nix/store" = lib.mkIf (cfg.useNixStoreImage || cfg.mountHostNixStore) (if cfg.writableStore then { + overlay = { + lowerdir = [ "/nix/.ro-store" ]; + upperdir = "/nix/.rw-store/upper"; + workdir = "/nix/.rw-store/work"; + }; + } else { + device = "/nix/.ro-store"; + options = [ "bind" ]; + }); + "/nix/.ro-store" = lib.mkIf cfg.useNixStoreImage { device = "/dev/disk/by-label/${nixStoreFilesystemLabel}"; neededForBoot = true; options = [ "ro" ]; @@ -1258,40 +1234,13 @@ in options = [ "mode=0755" ]; neededForBoot = true; }; - "/boot" = lib.mkIf (cfg.useBootLoader && cfg.bootPartition != null) { + "${config.boot.loader.efi.efiSysMountPoint}" = lib.mkIf (cfg.useBootLoader && cfg.bootPartition != null) { device = cfg.bootPartition; fsType = "vfat"; - noCheck = true; # fsck fails on a r/o filesystem }; } ]; - boot.initrd.systemd = lib.mkIf (config.boot.initrd.systemd.enable && cfg.writableStore) { - mounts = [{ - where = "/sysroot/nix/store"; - what = "overlay"; - type = "overlay"; - options = "lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/store,workdir=/sysroot/nix/.rw-store/work"; - wantedBy = ["initrd-fs.target"]; - before = ["initrd-fs.target"]; - requires = ["rw-store.service"]; - after = ["rw-store.service"]; - unitConfig.RequiresMountsFor = "/sysroot/nix/.ro-store"; - }]; - services.rw-store = { - before = [ "shutdown.target" ]; - conflicts = [ "shutdown.target" ]; - unitConfig = { - DefaultDependencies = false; - RequiresMountsFor = "/sysroot/nix/.rw-store"; - }; - serviceConfig = { - Type = "oneshot"; - ExecStart = "/bin/mkdir -p -m 0755 /sysroot/nix/.rw-store/store /sysroot/nix/.rw-store/work /sysroot/nix/store"; - }; - }; - }; - swapDevices = (if cfg.useDefaultFilesystems then mkVMOverride else mkDefault) [ ]; boot.initrd.luks.devices = (if cfg.useDefaultFilesystems then mkVMOverride else mkDefault) {}; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 0e0f4c7306a3..a004bd4b8664 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -804,6 +804,7 @@ in { qemu-vm-restrictnetwork = handleTest ./qemu-vm-restrictnetwork.nix {}; qemu-vm-volatile-root = runTest ./qemu-vm-volatile-root.nix; qemu-vm-external-disk-image = runTest ./qemu-vm-external-disk-image.nix; + qemu-vm-store = runTest ./qemu-vm-store.nix; qgis = handleTest ./qgis.nix { qgisPackage = pkgs.qgis; }; qgis-ltr = handleTest ./qgis.nix { qgisPackage = pkgs.qgis-ltr; }; qownnotes = handleTest ./qownnotes.nix {}; diff --git a/nixos/tests/qemu-vm-store.nix b/nixos/tests/qemu-vm-store.nix new file mode 100644 index 000000000000..9fb9f4baaafc --- /dev/null +++ b/nixos/tests/qemu-vm-store.nix @@ -0,0 +1,71 @@ +{ lib, ... }: { + + name = "qemu-vm-store"; + + meta.maintainers = with lib.maintainers; [ nikstur ]; + + nodes = { + sharedWritable = { + virtualisation.writableStore = true; + }; + + sharedReadOnly = { + virtualisation.writableStore = false; + }; + + imageWritable = { + virtualisation.useNixStoreImage = true; + virtualisation.writableStore = true; + }; + + imageReadOnly = { + virtualisation.useNixStoreImage = true; + virtualisation.writableStore = false; + }; + + fullDisk = { + virtualisation.useBootLoader = true; + }; + }; + + testScript = '' + build_derivation = """ + nix-build --option substitute false -E 'derivation { + name = "t"; + builder = "/bin/sh"; + args = ["-c" "echo something > $out"]; + system = builtins.currentSystem; + preferLocalBuild = true; + }' + """ + + start_all() + + with subtest("Nix Store is writable"): + sharedWritable.succeed(build_derivation) + imageWritable.succeed(build_derivation) + fullDisk.succeed(build_derivation) + + with subtest("Nix Store is read only"): + sharedReadOnly.fail(build_derivation) + imageReadOnly.fail(build_derivation) + + # Checking whether the fs type is 9P is just a proxy to test whether the + # Nix Store is shared. If we switch to a different technology (e.g. + # virtiofs) for sharing, we need to adjust these tests. + + with subtest("Nix store is shared from the host via 9P"): + sharedWritable.succeed("findmnt --kernel --type 9P /nix/.ro-store") + sharedReadOnly.succeed("findmnt --kernel --type 9P /nix/.ro-store") + + with subtest("Nix store is not shared via 9P"): + imageWritable.fail("findmnt --kernel --type 9P /nix/.ro-store") + imageReadOnly.fail("findmnt --kernel --type 9P /nix/.ro-store") + + with subtest("Nix store is not mounted separately"): + rootDevice = fullDisk.succeed("stat -c %d /") + nixStoreDevice = fullDisk.succeed("stat -c %d /nix/store") + assert rootDevice == nixStoreDevice, "Nix store is mounted separately from the root fs" + ''; + +} |
