summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlassulus <github@lassul.us>2024-07-18 19:34:51 +0200
committerGitHub <noreply@github.com>2024-07-18 19:34:51 +0200
commita62c421981c870b686ceeee05d98f5360b1b1625 (patch)
treef7db2a8a261e01bebe20a0d139d23942fd8f9954
parentMerge pull request #324438 from mweinelt/nss-3.102 (diff)
parentnixos/qemu-vm: remove creation of /etc/nixos (diff)
downloadnixpkgs-a62c421981c870b686ceeee05d98f5360b1b1625.tar.gz
Merge pull request #290730 from nikstur/qemu-vm-refactoring
qemu-vm.nix refactoring
-rw-r--r--nixos/modules/virtualisation/qemu-vm.nix87
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/qemu-vm-store.nix71
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"
+ '';
+
+}