summary refs log tree commit diff
diff options
context:
space:
mode:
authorWill Fancher <elvishjerricco@gmail.com>2023-10-23 17:40:34 -0400
committerWill Fancher <elvishjerricco@gmail.com>2023-10-23 17:40:34 -0400
commit99a47a5e357689a136fd917819fd3a26e3012be3 (patch)
tree954ffb6d9069652067af7c8ee1f728fde4833b38
parent8dfad603247387df1df4826b8bea58efc5d012d8 (diff)
downloadnixpkgs-99a47a5e357689a136fd917819fd3a26e3012be3.tar
nixpkgs-99a47a5e357689a136fd917819fd3a26e3012be3.tar.gz
nixpkgs-99a47a5e357689a136fd917819fd3a26e3012be3.tar.bz2
nixpkgs-99a47a5e357689a136fd917819fd3a26e3012be3.tar.lz
nixpkgs-99a47a5e357689a136fd917819fd3a26e3012be3.tar.xz
nixpkgs-99a47a5e357689a136fd917819fd3a26e3012be3.tar.zst
nixpkgs-99a47a5e357689a136fd917819fd3a26e3012be3.zip
systemd-stage-1: Enable more encrypted installer tests
-rw-r--r--nixos/modules/tasks/encrypted-devices.nix64
-rw-r--r--nixos/tests/installer-systemd-stage-1.nix8
-rw-r--r--nixos/tests/installer.nix4
3 files changed, 54 insertions, 22 deletions
diff --git a/nixos/modules/tasks/encrypted-devices.nix b/nixos/modules/tasks/encrypted-devices.nix
index 7837a34b498..ab3ccddf682 100644
--- a/nixos/modules/tasks/encrypted-devices.nix
+++ b/nixos/modules/tasks/encrypted-devices.nix
@@ -5,8 +5,22 @@ with lib;
 let
   fileSystems = config.system.build.fileSystems ++ config.swapDevices;
   encDevs = filter (dev: dev.encrypted.enable) fileSystems;
-  keyedEncDevs = filter (dev: dev.encrypted.keyFile != null) encDevs;
-  keylessEncDevs = filter (dev: dev.encrypted.keyFile == null) encDevs;
+
+  # With scripted initrd, devices with a keyFile have to be opened
+  # late, after file systems are mounted, because that could be where
+  # the keyFile is located. With systemd initrd, each individual
+  # systemd-cryptsetup@ unit has RequiresMountsFor= to delay until all
+  # the mount units for the key file are done; i.e. no special
+  # treatment is needed.
+  lateEncDevs =
+    if config.boot.initrd.systemd.enable
+    then { }
+    else filter (dev: dev.encrypted.keyFile != null) encDevs;
+  earlyEncDevs =
+    if config.boot.initrd.systemd.enable
+    then encDevs
+    else filter (dev: dev.encrypted.keyFile == null) encDevs;
+
   anyEncrypted =
     foldr (j: v: v || j.encrypted.enable) false encDevs;
 
@@ -39,11 +53,14 @@ let
         type = types.nullOr types.str;
         description = lib.mdDoc ''
           Path to a keyfile used to unlock the backing encrypted
-          device. At the time this keyfile is accessed, the
-          `neededForBoot` filesystems (see
-          `fileSystems.<name?>.neededForBoot`)
-          will have been mounted under `/mnt-root`,
-          so the keyfile path should usually start with "/mnt-root/".
+          device. When systemd stage 1 is not enabled, at the time
+          this keyfile is accessed, the `neededForBoot` filesystems
+          (see `utils.fsNeededForBoot`) will have been mounted under
+          `/mnt-root`, so the keyfile path should usually start with
+          "/mnt-root/". When systemd stage 1 is enabled,
+          `fsNeededForBoot` file systems will be mounted as needed
+          under `/sysroot`, and the keyfile will not be accessed until
+          its requisite mounts are done.
         '';
       };
     };
@@ -62,26 +79,41 @@ in
   };
 
   config = mkIf anyEncrypted {
-    assertions = map (dev: {
-      assertion = dev.encrypted.label != null;
-      message = ''
-        The filesystem for ${dev.mountPoint} has encrypted.enable set to true, but no encrypted.label set
-      '';
-    }) encDevs;
+    assertions = concatMap (dev: [
+      {
+        assertion = dev.encrypted.label != null;
+        message = ''
+          The filesystem for ${dev.mountPoint} has encrypted.enable set to true, but no encrypted.label set
+        '';
+      }
+      {
+        assertion =
+          config.boot.initrd.systemd.enable -> (
+            dev.encrypted.keyFile == null
+            || !lib.any (x: lib.hasPrefix x dev.encrypted.keyFile) ["/mnt-root" "$targetRoot"]
+          );
+        message = ''
+          Bad use of '/mnt-root' or '$targetRoot` in 'keyFile'.
+
+            When 'boot.initrd.systemd.enable' is enabled, file systems
+            are mounted at '/sysroot' instead of '/mnt-root'.
+        '';
+      }
+    ]) encDevs;
 
     boot.initrd = {
       luks = {
         devices =
           builtins.listToAttrs (map (dev: {
             name = dev.encrypted.label;
-            value = { device = dev.encrypted.blkDev; };
-          }) keylessEncDevs);
+            value = { device = dev.encrypted.blkDev; inherit (dev.encrypted) keyFile; };
+          }) earlyEncDevs);
         forceLuksSupportInInitrd = true;
       };
       postMountCommands =
         concatMapStrings (dev:
           "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.blkDev} ${dev.encrypted.label};\n"
-        ) keyedEncDevs;
+        ) lateEncDevs;
     };
   };
 }
diff --git a/nixos/tests/installer-systemd-stage-1.nix b/nixos/tests/installer-systemd-stage-1.nix
index 85155a6c682..608a21ef637 100644
--- a/nixos/tests/installer-systemd-stage-1.nix
+++ b/nixos/tests/installer-systemd-stage-1.nix
@@ -12,11 +12,11 @@
     btrfsSubvolDefault
     btrfsSubvolEscape
     btrfsSubvols
-    # encryptedFSWithKeyfile
+    encryptedFSWithKeyfile
     # grub1
-    # luksroot
-    # luksroot-format1
-    # luksroot-format2
+    luksroot
+    luksroot-format1
+    luksroot-format2
     # lvm
     separateBoot
     separateBootFat
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index 5111cedf925..4cd092756f5 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -511,7 +511,7 @@ let
       enableOCR = true;
       preBootCommands = ''
         machine.start()
-        machine.wait_for_text("Passphrase for")
+        machine.wait_for_text("[Pp]assphrase for")
         machine.send_chars("supersecret\n")
       '';
     };
@@ -765,7 +765,7 @@ in {
         encrypted.enable = true;
         encrypted.blkDev = "/dev/vda3";
         encrypted.label = "crypt";
-        encrypted.keyFile = "/mnt-root/keyfile";
+        encrypted.keyFile = "/${if systemdStage1 then "sysroot" else "mnt-root"}/keyfile";
       };
     '';
   };