diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix
index 31f1e22cda32c..92ba79b2bed33 100644
--- a/nixos/modules/system/boot/luksroot.nix
+++ b/nixos/modules/system/boot/luksroot.nix
@@ -157,19 +157,15 @@ let
local passphrase
while true; do
- echo -n "Passphrase for ${device}: "
passphrase=
while true; do
if [ -e /crypt-ramfs/passphrase ]; then
- echo "reused"
+ echo "Passphrase for ${device}: reused"
passphrase=$(cat /crypt-ramfs/passphrase)
break
else
- # ask cryptsetup-askpass
echo -n "${device}" > /crypt-ramfs/device
-
- # and try reading it from /dev/console with a timeout
- IFS= read -t 1 -r passphrase
+ passphrase="$(askPassword "Passphrase for ${device}: ")"
if [ -n "$passphrase" ]; then
${if luks.reusePassphrases then ''
# remember it for the next device
@@ -253,9 +249,7 @@ let
for try in $(seq 3); do
${optionalString yubikey.twoFactor ''
- echo -n "Enter two-factor passphrase: "
- read -r k_user
- echo
+ k_user="$(askPassword "Enter two-factor passphrase: ")"
''}
if [ ! -z "$k_user" ]; then
@@ -336,16 +330,15 @@ let
gpg --card-status > /dev/null 2> /dev/null
for try in $(seq 3); do
- echo -n "PIN for GPG Card associated with device ${device}: "
pin=
while true; do
if [ -e /crypt-ramfs/passphrase ]; then
- echo "reused"
+ echo "PIN for GPG Card associated with device ${device}: reused"
pin=$(cat /crypt-ramfs/passphrase)
break
else
# and try reading it from /dev/console with a timeout
- IFS= read -t 1 -r pin
+ pin="$(askPassword "PIN for GPG Card associated with device ${device}: ")"
if [ -n "$pin" ]; then
${if luks.reusePassphrases then ''
# remember it for the next device
@@ -396,8 +389,7 @@ let
${if fido2.passwordLess then ''
export passphrase=""
'' else ''
- read -rsp "FIDO2 salt for ${device}: " passphrase
- echo
+ passphrase="$(askPassword "FIDO2 salt for ${device}: ")"
''}
${optionalString (lib.versionOlder kernelPackages.kernel.version "5.4") ''
echo "On systems with Linux Kernel < 5.4, it might take a while to initialize the CRNG, you might want to use linuxPackages_latest."
@@ -419,24 +411,6 @@ let
''}
'';
- askPass = pkgs.writeScriptBin "cryptsetup-askpass" ''
- #!/bin/sh
-
- ${commonFunctions}
-
- while true; do
- wait_target "luks" /crypt-ramfs/device 10 "LUKS to request a passphrase" || die "Passphrase is not requested now"
- device=$(cat /crypt-ramfs/device)
-
- echo -n "Passphrase for $device: "
- IFS= read -rs passphrase
- echo
-
- rm /crypt-ramfs/device
- echo -n "$passphrase" > /crypt-ramfs/passphrase
- done
- '';
-
preLVM = filterAttrs (n: v: v.preLVM) luks.devices;
postLVM = filterAttrs (n: v: !v.preLVM) luks.devices;
@@ -797,8 +771,6 @@ in
# copy the cryptsetup binary and it's dependencies
boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.cryptsetup}/bin/cryptsetup
- copy_bin_and_libs ${askPass}/bin/cryptsetup-askpass
- sed -i s,/bin/sh,$out/bin/sh, $out/bin/cryptsetup-askpass
${optionalString luks.yubikeySupport ''
copy_bin_and_libs ${pkgs.yubikey-personalization}/bin/ykchalresp
diff --git a/nixos/modules/system/boot/plymouth.nix b/nixos/modules/system/boot/plymouth.nix
index 23fce22366d8e..d748cab1c463b 100644
--- a/nixos/modules/system/boot/plymouth.nix
+++ b/nixos/modules/system/boot/plymouth.nix
@@ -111,7 +111,7 @@ in
mkdir -p $out/lib/plymouth/renderers
# module might come from a theme
- cp ${themesEnv}/lib/plymouth/{text,details,$moduleName}.so $out/lib/plymouth
+ cp ${themesEnv}/lib/plymouth/{text,details,label,$moduleName}.so $out/lib/plymouth
cp ${plymouth}/lib/plymouth/renderers/{drm,frame-buffer}.so $out/lib/plymouth/renderers
mkdir -p $out/share/plymouth/themes
@@ -120,7 +120,7 @@ in
# copy themes into working directory for patching
mkdir themes
# use -L to copy the directories proper, not the symlinks to them
- cp -r -L ${themesEnv}/share/plymouth/themes/{text,details,${cfg.theme}} themes
+ cp -r -L ${themesEnv}/share/plymouth/themes/{text,details,spinner,${cfg.theme}} themes
# patch out any attempted references to the theme or plymouth's themes directory
chmod -R +w themes
@@ -131,6 +131,15 @@ in
cp -r themes/* $out/share/plymouth/themes
cp ${cfg.logo} $out/share/plymouth/logo.png
+
+ mkdir -p $out/usr/share/fonts/truetype
+ mkdir -p $out/etc/fonts/2.11/conf.d
+ cp -r ${pkgs.cantarell-fonts}/share/fonts/cantarell/Cantarell-{Thin,Regular}.otf $out/usr/share/fonts/truetype
+ cp -r ${pkgs.dejavu_fonts.minimal}/share/fonts/truetype/DejaVuSans.ttf $out/usr/share/fonts/truetype
+
+ cp ${pkgs.fontconfig.out}/share/fontconfig/conf.avail/60-latin.conf $out/etc/fonts/2.11/conf.d
+ cp ${pkgs.fontconfig.out}/etc/fonts/fonts.conf $out/etc/fonts/2.11
+ sed -i 's@
${pkgs.dejavu_fonts.minimal}@/usr/share/fonts@g' $out/etc/fonts/2.11/fonts.conf
'';
boot.initrd.extraUtilsCommandsTest = ''
@@ -143,17 +152,22 @@ in
sed -i '/loginctl/d' $out/71-seat.rules
'';
- # We use `mkAfter` to ensure that LUKS password prompt would be shown earlier than the splash screen.
- boot.initrd.preLVMCommands = mkAfter ''
- mkdir -p /etc/plymouth
+ boot.initrd.preLogCommands = ''
+ mkdir -p /etc/plymouth /usr/share
ln -s ${configFile} /etc/plymouth/plymouthd.conf
ln -s $extraUtils/share/plymouth/plymouthd.defaults /etc/plymouth/plymouthd.defaults
ln -s $extraUtils/share/plymouth/logo.png /etc/plymouth/logo.png
ln -s $extraUtils/share/plymouth/themes /etc/plymouth/themes
ln -s $extraUtils/lib/plymouth /etc/plymouth/plugins
+ ln -s $extraUtils/etc/fonts /etc/fonts
+ ln -s $extraUtils/usr/share/fonts /usr/share/fonts
plymouthd --mode=boot --pid-file=/run/plymouth/pid --attach-to-session
plymouth show-splash
+
+ askPassword() {
+ plymouth ask-for-password --prompt="$1"
+ }
'';
boot.initrd.postMountCommands = ''
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index 607aec87f01e5..b97a5035f41a7 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -62,11 +62,6 @@ EOF
trap 'fail' 0
-# Print a greeting.
-echo
-echo "[1;32m<<< NixOS Stage 1 >>>[0m"
-echo
-
# Make several required directories.
mkdir -p /etc/udev
touch /etc/fstab # to shut up mount
@@ -116,6 +111,23 @@ source @earlyMountScript@
mkdir -p /tmp
mkfifo /tmp/stage-1-init.log.fifo
logOutFd=8 && logErrFd=9
+
+# askPassword
+askPassword() {
+ # Ensure that we don't reset the echo flag.
+ curStatus=$(stty -g)
+ stty -echo
+
+ printf "%s" "$1" >&2
+ IFS= read -r password
+ printf "\n" >&2
+
+ stty "$curStatus"
+ printf "%s" "$password"
+}
+
+@preLogCommands@
+
eval "exec $logOutFd>&1 $logErrFd>&2"
if test -w /dev/kmsg; then
tee -i < /tmp/stage-1-init.log.fifo /proc/self/fd/"$logOutFd" | while read -r line; do
@@ -129,6 +141,10 @@ else
fi
exec > /tmp/stage-1-init.log.fifo 2>&1
+# Print a greeting.
+echo
+echo -e "\e[1;3m<<< NixOS Stage 1 >>>\e[0m"
+echo
# Process the kernel command line.
export stage2Init=/init
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index dfd158e2d75f4..dbc757dcea73a 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -280,7 +280,7 @@ let
inherit (config.system.build) earlyMountScript;
inherit (config.boot.initrd) checkJournalingFS
- preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules;
+ preLVMCommands preLogCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules;
resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
(filter (sd: hasPrefix "/dev/" sd.device && !sd.randomEncryption.enable
@@ -438,6 +438,14 @@ in
'';
};
+ boot.initrd.preLogCommands = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Shell commands to be executed immediately before setting up logging.
+ '';
+ };
+
boot.initrd.preDeviceCommands = mkOption {
default = "";
type = types.lines;
diff --git a/nixos/modules/tasks/filesystems/bcachefs.nix b/nixos/modules/tasks/filesystems/bcachefs.nix
index 5fda24adb9782..806d2c25a5b63 100644
--- a/nixos/modules/tasks/filesystems/bcachefs.nix
+++ b/nixos/modules/tasks/filesystems/bcachefs.nix
@@ -7,18 +7,13 @@ let
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
+ # repeat until sucessfully unlocked
+ until askPassword "Enter passphrase for $name: " | bcachefs unlock $path; do
printf "unlocking failed!\n"
- prompt $name
done
printf "unlocking successful.\n"
fi
diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index 43347161a84c6..bfa9b10077a0f 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -421,8 +421,29 @@ in
fi
poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool.
fi
- ${lib.optionalString cfgZfs.requestEncryptionCredentials ''
- zfs load-key -a
+ ${optionalString cfgZfs.requestEncryptionCredentials ''
+ zfs list -r -H -o encryptionroot,keystatus,keylocation "${pool}" | sort | uniq | while IFS=" " read encryptionroot keystatus keylocation; do
+ if [ "$keystatus" != "unavailable" -o "$keylocation" == "none" ]; then
+ continue
+ fi
+
+ if [ "$keylocation" != "prompt" ]; then
+ "${packages.zfsUser}/bin/zfs" load-key "$encryptionroot" || die "Failed to load key for $encryptionroot"
+ continue
+ fi
+
+ success=
+ for i in $(seq 1 3); do
+ if askPassword "Enter key for $encryptionroot: " | zfs load-key "$encryptionroot"; then
+ success=1
+ break
+ fi
+ done
+
+ if [ -z "$success" ]; then
+ die "Failed to load key for $encryptionroot"
+ fi
+ done
''}
'') rootPools));
};