diff --git a/nixos/modules/system/boot/plymouth.nix b/nixos/modules/system/boot/plymouth.nix index 78ae8e9d20b7..8b57cae3c40d 100644 --- a/nixos/modules/system/boot/plymouth.nix +++ b/nixos/modules/system/boot/plymouth.nix @@ -4,7 +4,10 @@ with lib; let - inherit (pkgs) plymouth nixos-icons; + inherit (pkgs) nixos-icons; + plymouth = pkgs.plymouth.override { + systemd = config.boot.initrd.systemd.package; + }; cfg = config.boot.plymouth; opt = options.boot.plymouth; @@ -143,7 +146,88 @@ in systemd.services.systemd-ask-password-plymouth.wantedBy = [ "multi-user.target" ]; systemd.paths.systemd-ask-password-plymouth.wantedBy = [ "multi-user.target" ]; - boot.initrd.extraUtilsCommands = '' + boot.initrd.systemd = { + extraBin.plymouth = "${plymouth}/bin/plymouth"; # for the recovery shell + storePaths = [ + "${lib.getBin config.boot.initrd.systemd.package}/bin/systemd-tty-ask-password-agent" + "${plymouth}/bin/plymouthd" + "${plymouth}/sbin/plymouthd" + ]; + packages = [ plymouth ]; # systemd units + contents = { + # Files + "/etc/plymouth/plymouthd.conf".source = configFile; + "/etc/plymouth/plymouthd.defaults".source = "${plymouth}/share/plymouth/plymouthd.defaults"; + "/etc/plymouth/logo.png".source = cfg.logo; + # Directories + "/etc/plymouth/plugins".source = pkgs.runCommand "plymouth-initrd-plugins" {} '' + # Check if the actual requested theme is here + if [[ ! -d ${themesEnv}/share/plymouth/themes/${cfg.theme} ]]; then + echo "The requested theme: ${cfg.theme} is not provided by any of the packages in boot.plymouth.themePackages" + exit 1 + fi + + moduleName="$(sed -n 's,ModuleName *= *,,p' ${themesEnv}/share/plymouth/themes/${cfg.theme}/${cfg.theme}.plymouth)" + + mkdir -p $out/renderers + # module might come from a theme + cp ${themesEnv}/lib/plymouth/{text,details,label,$moduleName}.so $out + cp ${plymouth}/lib/plymouth/renderers/{drm,frame-buffer}.so $out/renderers + ''; + "/etc/plymouth/themes".source = pkgs.runCommand "plymouth-initrd-themes" {} '' + # Check if the actual requested theme is here + if [[ ! -d ${themesEnv}/share/plymouth/themes/${cfg.theme} ]]; then + echo "The requested theme: ${cfg.theme} is not provided by any of the packages in boot.plymouth.themePackages" + exit 1 + fi + + mkdir $out + cp -r ${themesEnv}/share/plymouth/themes/${cfg.theme} $out + # Copy more themes if the theme depends on others + for theme in $(grep -hRo '/etc/plymouth/themes/.*$' ${themesEnv} | xargs -n1 basename); do + if [[ -d "${themesEnv}/theme" ]]; then + cp -r "${themesEnv}/theme" $out + fi + done + ''; + + # Fonts + "/etc/plymouth/fonts".source = pkgs.runCommand "plymouth-initrd-fonts" {} '' + mkdir -p $out + cp ${cfg.font} $out + ''; + "/etc/fonts/fonts.conf".text = '' + + + + /etc/plymouth/fonts + + ''; + }; + # Properly enable units. These are the units that arch copies + services = { + plymouth-halt.wantedBy = [ "halt.target" ]; + plymouth-kexec.wantedBy = [ "kexec.target" ]; + plymouth-poweroff.wantedBy = [ "poweroff.target" ]; + plymouth-quit-wait.wantedBy = [ "multi-user.target" ]; + plymouth-quit.wantedBy = [ "multi-user.target" ]; + plymouth-read-write.wantedBy = [ "sysinit.target" ]; + plymouth-reboot.wantedBy = [ "reboot.target" ]; + plymouth-start.wantedBy = [ "initrd-switch-root.target" "sysinit.target" ]; + plymouth-switch-root-initramfs.wantedBy = [ "halt.target" "kexec.target" "plymouth-switch-root-initramfs.service" "poweroff.target" "reboot.target" ]; + plymouth-switch-root.wantedBy = [ "initrd-switch-root.target" ]; + }; + }; + + # Insert required udev rules. We take stage 2 systemd because the udev + # rules are only generated when building with logind. + boot.initrd.services.udev.packages = [ (pkgs.runCommand "initrd-plymouth-udev-rules" {} '' + mkdir -p $out/etc/udev/rules.d + cp ${config.systemd.package.out}/lib/udev/rules.d/{70-uaccess,71-seat}.rules $out/etc/udev/rules.d + sed -i '/loginctl/d' $out/etc/udev/rules.d/71-seat.rules + '') ]; + + boot.initrd.extraUtilsCommands = lib.mkIf (!config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${plymouth}/bin/plymouth copy_bin_and_libs ${plymouth}/bin/plymouthd @@ -198,18 +282,18 @@ in EOF ''; - boot.initrd.extraUtilsCommandsTest = '' + boot.initrd.extraUtilsCommandsTest = mkIf (!config.boot.initrd.enable) '' $out/bin/plymouthd --help >/dev/null $out/bin/plymouth --help >/dev/null ''; - boot.initrd.extraUdevRulesCommands = '' + boot.initrd.extraUdevRulesCommands = mkIf (!config.boot.initrd.enable) '' cp ${config.systemd.package}/lib/udev/rules.d/{70-uaccess,71-seat}.rules $out 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 '' + boot.initrd.preLVMCommands = mkIf (!config.boot.initrd.enable) (mkAfter '' mkdir -p /etc/plymouth mkdir -p /run/plymouth ln -s ${configFile} /etc/plymouth/plymouthd.conf @@ -221,16 +305,16 @@ in plymouthd --mode=boot --pid-file=/run/plymouth/pid --attach-to-session plymouth show-splash - ''; + ''); - boot.initrd.postMountCommands = '' + boot.initrd.postMountCommands = mkIf (!config.boot.initrd.enable) '' plymouth update-root-fs --new-root-dir="$targetRoot" ''; # `mkBefore` to ensure that any custom prompts would be visible. - boot.initrd.preFailCommands = mkBefore '' + boot.initrd.preFailCommands = mkIf (!config.boot.initrd.enable) (mkBefore '' plymouth quit --wait - ''; + ''); };