about summary refs log tree commit diff
path: root/nixos/tests/installer.nix
diff options
context:
space:
mode:
authoraszlig2015-05-21 12:42:00 +0200
committeraszlig2015-05-21 13:21:41 +0200
commit1f34503010bee487b36ed5256fa27e3d2d29c968 (patch)
tree5dec372a800ea033e6c612675c31f533d488a658 /nixos/tests/installer.nix
parent3b396701fdc054795656562295d1092b72c192db (diff)
nixos/tests/installer: Add test for LUKS rootfs.
This serves as a regression test for #7859.

It's pretty straightforward, except from the fact that nixos-generate-
config doesn't detect LUKS devices and the "sleep 60".

As for the former, I have tried to add support for LUKS devices for
nixos-generate-config, but it's not so easy as it sounds, because we
need to create a device tree across all possible mappers and/or LVM up
to the "real" device and then decide whether it is relevant to what is
currently mounted. So I guess this is something for the nixpart branch
(see #2079).

And the latter isn't very trivial as well, because the LUKS passphrase
prompt is issued on /dev/console, which is the last "console=..." kernel
parameter (thus the `mkAfter`). So we can't simply grep the log, because
the prompt ends up being on one terminal only (tty0) and using select()
on $machine->{socket} doesn't work very well, because the FD is always
"ready for read". If we would read the FD, we would conflict with
$machine->connect and end up having an inconsistent state. Another idea
would be to use multithreading to do $machine->connect while feeding the
passphrase prompt in a loop and stop the thread once $machine->connect
is done. Turns out that this is not so easy as well, because the threads
need to share the $machine object and of course need to do properly
locking.

In the end I decided to use the "blindly hope that 60 seconds is enough"
approach for now and come up with a better solution later. Other VM
tests surely use sleep as well, but it's $machine->sleep, which is bound
to the clock of the VM, so if the build machine is on high load, a
$machine->sleep gets properly delayed but the timer outside the VM won't
get that delay, so the test is not deterministic.

Tested against the following revisions:

5e3fe39: Before the libgcrypt cleanup (a71f78a) that broke cryptsetup.
69a6848: While cryptsetup was broken (obviously the test failed).
15faa43: After cryptsetup has been switched to OpenSSL (fd588f9).

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Diffstat (limited to 'nixos/tests/installer.nix')
-rw-r--r--nixos/tests/installer.nix37
1 files changed, 37 insertions, 0 deletions
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index 8ef247d6c4df..a67068dc30a5 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -334,6 +334,43 @@ in {
         '';
     };
 
+  # Boot off an encrypted root partition
+  luksroot = makeInstallerTest "luksroot"
+    { createPartitions = ''
+        $machine->succeed(
+          "parted /dev/vda mklabel msdos",
+          "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
+          "parted /dev/vda -- mkpart primary linux-swap 50M 1024M",
+          "parted /dev/vda -- mkpart primary 1024M -1s", # LUKS
+          "udevadm settle",
+          "mkswap /dev/vda2 -L swap",
+          "swapon -L swap",
+          "modprobe dm_mod dm_crypt",
+          "echo -n supersecret | cryptsetup luksFormat -q /dev/vda3 -",
+          "echo -n supersecret | cryptsetup luksOpen --key-file - /dev/vda3 cryptroot",
+          "mkfs.ext3 -L nixos /dev/mapper/cryptroot",
+          "mount LABEL=nixos /mnt",
+          "mkfs.ext3 -L boot /dev/vda1",
+          "mkdir -p /mnt/boot",
+          "mount LABEL=boot /mnt/boot",
+        );
+      '';
+      # XXX: Currently, generate-config doesn't detect LUKS yet.
+      extraConfig = ''
+        boot.kernelParams = lib.mkAfter [ "console=tty0" ];
+        boot.initrd.luks.devices = lib.singleton {
+          name = "cryptroot";
+          device = "/dev/vda3";
+          preLVM = true;
+        };
+      '';
+      preBootCommands = ''
+        $machine->start;
+        sleep 60; # XXX: Hopefully this is long enough :-/
+        $machine->sendChars("supersecret\n");
+      '';
+    };
+
   swraid = makeInstallerTest "swraid"
     { createPartitions =
         ''