about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorhyperfekt <adni.online@gmail.com>2018-11-03 02:07:36 +0000
committerhyperfekt <adni.online@gmail.com>2018-11-06 09:26:35 +0100
commit95b2b6f541310ffff9040cdc8cf6f70d7a5ceee5 (patch)
treeee733fe2ff46e00286d19d4eacf6f8ffa27a03a3 /nixos
parent482228919c80d283130e30afa2bfdee05a5bfb92 (diff)
downloadnixlib-95b2b6f541310ffff9040cdc8cf6f70d7a5ceee5.tar
nixlib-95b2b6f541310ffff9040cdc8cf6f70d7a5ceee5.tar.gz
nixlib-95b2b6f541310ffff9040cdc8cf6f70d7a5ceee5.tar.bz2
nixlib-95b2b6f541310ffff9040cdc8cf6f70d7a5ceee5.tar.lz
nixlib-95b2b6f541310ffff9040cdc8cf6f70d7a5ceee5.tar.xz
nixlib-95b2b6f541310ffff9040cdc8cf6f70d7a5ceee5.tar.zst
nixlib-95b2b6f541310ffff9040cdc8cf6f70d7a5ceee5.zip
nixos/bcachefs: enable encrypted root
Enables automatic decryption for bcachefs-formatted filesystems needed during boot.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/tasks/filesystems/bcachefs.nix60
1 files changed, 52 insertions, 8 deletions
diff --git a/nixos/modules/tasks/filesystems/bcachefs.nix b/nixos/modules/tasks/filesystems/bcachefs.nix
index dfb8106d9a5e..5fda24adb978 100644
--- a/nixos/modules/tasks/filesystems/bcachefs.nix
+++ b/nixos/modules/tasks/filesystems/bcachefs.nix
@@ -1,21 +1,65 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, utils, ... }:
 
 with lib;
 
 let
 
-  inInitrd = any (fs: fs == "bcachefs") config.boot.initrd.supportedFilesystems;
+  bootFs = filterAttrs (n: fs: (fs.fsType == "bcachefs") && (utils.fsNeededForBoot fs)) config.fileSystems;
+
+  commonFunctions = ''
+    prompt() {
+        local name="$1"
+        printf "enter passphrase for $name: "
+    }
+    tryUnlock() {
+        local name="$1"
+        local path="$2"
+        if bcachefs unlock -c $path > /dev/null 2> /dev/null; then    # test for encryption
+            prompt $name
+            until bcachefs unlock $path 2> /dev/null; do              # repeat until sucessfully unlocked
+                printf "unlocking failed!\n"
+                prompt $name
+            done
+            printf "unlocking successful.\n"
+        fi
+    }
+  '';
+
+  openCommand = name: fs:
+    let
+      # we need only unlock one device manually, and cannot pass multiple at once
+      # remove this adaptation when bcachefs implements mounting by filesystem uuid
+      # also, implement automatic waiting for the constituent devices when that happens
+      # bcachefs does not support mounting devices with colons in the path, ergo we don't (see #49671)
+      firstDevice = head (splitString ":" fs.device);
+    in
+      ''
+        tryUnlock ${name} ${firstDevice}
+      '';
 
 in
 
 {
-  config = mkIf (any (fs: fs == "bcachefs") config.boot.supportedFilesystems) {
+  config = mkIf (elem "bcachefs" config.boot.supportedFilesystems) (mkMerge [
+    {
+      system.fsPackages = [ pkgs.bcachefs-tools ];
+
+      # use kernel package with bcachefs support until it's in mainline
+      boot.kernelPackages = pkgs.linuxPackages_testing_bcachefs;
+    }
 
-    system.fsPackages = [ pkgs.bcachefs-tools ];
+    (mkIf ((elem "bcachefs" config.boot.initrd.supportedFilesystems) || (bootFs != {})) {
+      # the cryptographic modules are required only for decryption attempts
+      boot.initrd.availableKernelModules = [ "bcachefs" "chacha20" "poly1305" ];
 
-    # use kernel package with bcachefs support until it's in mainline
-    boot.kernelPackages = pkgs.linuxPackages_testing_bcachefs;
-    boot.initrd.availableKernelModules = mkIf inInitrd [ "bcachefs" ];
+      boot.initrd.extraUtilsCommands = ''
+        copy_bin_and_libs ${pkgs.bcachefs-tools}/bin/bcachefs
+      '';
+      boot.initrd.extraUtilsCommandsTest = ''
+        $out/bin/bcachefs version
+      '';
 
-  };
+      boot.initrd.postDeviceCommands = commonFunctions + concatStrings (mapAttrsToList openCommand bootFs);
+    })
+  ]);
 }