at 24.11-pre 14 kB view raw
1{ config, lib, options, pkgs, ... }: 2 3with lib; 4 5let 6 7 plymouth = pkgs.plymouth.override { 8 systemd = config.boot.initrd.systemd.package; 9 }; 10 11 cfg = config.boot.plymouth; 12 opt = options.boot.plymouth; 13 14 nixosBreezePlymouth = pkgs.plasma5Packages.breeze-plymouth.override { 15 logoFile = cfg.logo; 16 logoName = "nixos"; 17 osName = "NixOS"; 18 osVersion = config.system.nixos.release; 19 }; 20 21 plymouthLogos = pkgs.runCommand "plymouth-logos" { inherit (cfg) logo; } '' 22 mkdir -p $out 23 24 # For themes that are compiled with PLYMOUTH_LOGO_FILE 25 mkdir -p $out/etc/plymouth 26 ln -s $logo $out/etc/plymouth/logo.png 27 28 # Logo for bgrt theme 29 # Note this is technically an abuse of watermark for the bgrt theme 30 # See: https://gitlab.freedesktop.org/plymouth/plymouth/-/issues/95#note_813768 31 mkdir -p $out/share/plymouth/themes/spinner 32 ln -s $logo $out/share/plymouth/themes/spinner/watermark.png 33 34 # Logo for spinfinity theme 35 # See: https://gitlab.freedesktop.org/plymouth/plymouth/-/issues/106 36 mkdir -p $out/share/plymouth/themes/spinfinity 37 ln -s $logo $out/share/plymouth/themes/spinfinity/header-image.png 38 ''; 39 40 themesEnv = pkgs.buildEnv { 41 name = "plymouth-themes"; 42 paths = [ 43 plymouth 44 plymouthLogos 45 ] ++ cfg.themePackages; 46 }; 47 48 configFile = pkgs.writeText "plymouthd.conf" '' 49 [Daemon] 50 ShowDelay=0 51 DeviceTimeout=8 52 Theme=${cfg.theme} 53 ${cfg.extraConfig} 54 ''; 55 56in 57 58{ 59 60 options = { 61 62 boot.plymouth = { 63 64 enable = mkEnableOption "Plymouth boot splash screen"; 65 66 font = mkOption { 67 default = "${pkgs.dejavu_fonts.minimal}/share/fonts/truetype/DejaVuSans.ttf"; 68 defaultText = literalExpression ''"''${pkgs.dejavu_fonts.minimal}/share/fonts/truetype/DejaVuSans.ttf"''; 69 type = types.path; 70 description = '' 71 Font file made available for displaying text on the splash screen. 72 ''; 73 }; 74 75 themePackages = mkOption { 76 default = lib.optional (cfg.theme == "breeze") nixosBreezePlymouth; 77 defaultText = literalMD '' 78 A NixOS branded variant of the breeze theme when 79 `config.${opt.theme} == "breeze"`, otherwise 80 `[ ]`. 81 ''; 82 type = types.listOf types.package; 83 description = '' 84 Extra theme packages for plymouth. 85 ''; 86 }; 87 88 theme = mkOption { 89 default = "bgrt"; 90 type = types.str; 91 description = '' 92 Splash screen theme. 93 ''; 94 }; 95 96 logo = mkOption { 97 type = types.path; 98 # Dimensions are 48x48 to match GDM logo 99 default = "${pkgs.nixos-icons}/share/icons/hicolor/48x48/apps/nix-snowflake-white.png"; 100 defaultText = literalExpression ''"''${pkgs.nixos-icons}/share/icons/hicolor/48x48/apps/nix-snowflake-white.png"''; 101 example = literalExpression '' 102 pkgs.fetchurl { 103 url = "https://nixos.org/logo/nixos-hires.png"; 104 sha256 = "1ivzgd7iz0i06y36p8m5w48fd8pjqwxhdaavc0pxs7w1g7mcy5si"; 105 } 106 ''; 107 description = '' 108 Logo which is displayed on the splash screen. 109 Currently supports PNG file format only. 110 ''; 111 }; 112 113 extraConfig = mkOption { 114 type = types.lines; 115 default = ""; 116 description = '' 117 Literal string to append to `configFile` 118 and the config file generated by the plymouth module. 119 ''; 120 }; 121 122 }; 123 124 }; 125 126 config = mkIf cfg.enable { 127 128 boot.kernelParams = [ "splash" ]; 129 130 # To be discoverable by systemd. 131 environment.systemPackages = [ plymouth ]; 132 133 environment.etc."plymouth/plymouthd.conf".source = configFile; 134 environment.etc."plymouth/plymouthd.defaults".source = "${plymouth}/share/plymouth/plymouthd.defaults"; 135 environment.etc."plymouth/logo.png".source = cfg.logo; 136 environment.etc."plymouth/themes".source = "${themesEnv}/share/plymouth/themes"; 137 # XXX: Needed because we supply a different set of plugins in initrd. 138 environment.etc."plymouth/plugins".source = "${plymouth}/lib/plymouth"; 139 140 systemd.tmpfiles.rules = [ 141 "d /run/plymouth 0755 root root 0 -" 142 "L+ /run/plymouth/plymouthd.defaults - - - - /etc/plymouth/plymouthd.defaults" 143 "L+ /run/plymouth/themes - - - - /etc/plymouth/themes" 144 "L+ /run/plymouth/plugins - - - - /etc/plymouth/plugins" 145 ]; 146 147 systemd.packages = [ plymouth ]; 148 149 systemd.services.plymouth-kexec.wantedBy = [ "kexec.target" ]; 150 systemd.services.plymouth-halt.wantedBy = [ "halt.target" ]; 151 systemd.services.plymouth-quit-wait.wantedBy = [ "multi-user.target" ]; 152 systemd.services.plymouth-quit.wantedBy = [ "multi-user.target" ]; 153 systemd.services.plymouth-poweroff.wantedBy = [ "poweroff.target" ]; 154 systemd.services.plymouth-reboot.wantedBy = [ "reboot.target" ]; 155 systemd.services.plymouth-read-write.wantedBy = [ "sysinit.target" ]; 156 systemd.services.systemd-ask-password-plymouth.wantedBy = [ "multi-user.target" ]; 157 systemd.paths.systemd-ask-password-plymouth.wantedBy = [ "multi-user.target" ]; 158 159 # Prevent Plymouth taking over the screen during system updates. 160 systemd.services.plymouth-start.restartIfChanged = false; 161 162 boot.initrd.systemd = { 163 extraBin.plymouth = "${plymouth}/bin/plymouth"; # for the recovery shell 164 storePaths = [ 165 "${lib.getBin config.boot.initrd.systemd.package}/bin/systemd-tty-ask-password-agent" 166 "${plymouth}/bin/plymouthd" 167 "${plymouth}/sbin/plymouthd" 168 ]; 169 packages = [ plymouth ]; # systemd units 170 contents = { 171 # Files 172 "/etc/plymouth/plymouthd.conf".source = configFile; 173 "/etc/plymouth/logo.png".source = cfg.logo; 174 "/etc/plymouth/plymouthd.defaults".source = "${plymouth}/share/plymouth/plymouthd.defaults"; 175 # Directories 176 "/etc/plymouth/plugins".source = pkgs.runCommand "plymouth-initrd-plugins" {} '' 177 # Check if the actual requested theme is here 178 if [[ ! -d ${themesEnv}/share/plymouth/themes/${cfg.theme} ]]; then 179 echo "The requested theme: ${cfg.theme} is not provided by any of the packages in boot.plymouth.themePackages" 180 exit 1 181 fi 182 183 moduleName="$(sed -n 's,ModuleName *= *,,p' ${themesEnv}/share/plymouth/themes/${cfg.theme}/${cfg.theme}.plymouth)" 184 185 mkdir -p $out/renderers 186 # module might come from a theme 187 cp ${themesEnv}/lib/plymouth/*.so $out 188 cp ${plymouth}/lib/plymouth/renderers/*.so $out/renderers 189 # useless in the initrd, and adds several megabytes to the closure 190 rm $out/renderers/x11.so 191 ''; 192 "/etc/plymouth/themes".source = pkgs.runCommand "plymouth-initrd-themes" {} '' 193 # Check if the actual requested theme is here 194 if [[ ! -d ${themesEnv}/share/plymouth/themes/${cfg.theme} ]]; then 195 echo "The requested theme: ${cfg.theme} is not provided by any of the packages in boot.plymouth.themePackages" 196 exit 1 197 fi 198 199 mkdir -p $out/${cfg.theme} 200 cp -r ${themesEnv}/share/plymouth/themes/${cfg.theme}/* $out/${cfg.theme} 201 # Copy more themes if the theme depends on others 202 for theme in $(grep -hRo '/share/plymouth/themes/.*$' $out | xargs -n1 basename); do 203 if [[ -d "${themesEnv}/share/plymouth/themes/$theme" ]]; then 204 if [[ ! -d "$out/$theme" ]]; then 205 echo "Adding dependent theme: $theme" 206 mkdir -p "$out/$theme" 207 cp -r "${themesEnv}/share/plymouth/themes/$theme"/* "$out/$theme" 208 fi 209 else 210 echo "Missing theme dependency: $theme" 211 fi 212 done 213 # Fixup references 214 for theme in $out/*/*.plymouth; do 215 sed -i "s,${builtins.storeDir}/.*/share/plymouth/themes,$out," "$theme" 216 done 217 ''; 218 219 # Fonts 220 "/etc/plymouth/fonts".source = pkgs.runCommand "plymouth-initrd-fonts" {} '' 221 mkdir -p $out 222 cp ${cfg.font} $out 223 ''; 224 "/etc/fonts/fonts.conf".text = '' 225 <?xml version="1.0"?> 226 <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> 227 <fontconfig> 228 <dir>/etc/plymouth/fonts</dir> 229 </fontconfig> 230 ''; 231 }; 232 # Properly enable units. These are the units that arch copies 233 services = { 234 plymouth-halt.wantedBy = [ "halt.target" ]; 235 plymouth-kexec.wantedBy = [ "kexec.target" ]; 236 plymouth-poweroff.wantedBy = [ "poweroff.target" ]; 237 plymouth-quit-wait.wantedBy = [ "multi-user.target" ]; 238 plymouth-quit.wantedBy = [ "multi-user.target" ]; 239 plymouth-read-write.wantedBy = [ "sysinit.target" ]; 240 plymouth-reboot.wantedBy = [ "reboot.target" ]; 241 plymouth-start.wantedBy = [ "initrd-switch-root.target" "sysinit.target" ]; 242 plymouth-switch-root-initramfs.wantedBy = [ "halt.target" "kexec.target" "plymouth-switch-root-initramfs.service" "poweroff.target" "reboot.target" ]; 243 plymouth-switch-root.wantedBy = [ "initrd-switch-root.target" ]; 244 }; 245 # Link in runtime files before starting 246 services.plymouth-start.preStart = '' 247 mkdir -p /run/plymouth 248 ln -sf /etc/plymouth/{plymouthd.defaults,themes,plugins} /run/plymouth/ 249 ''; 250 }; 251 252 # Insert required udev rules. We take stage 2 systemd because the udev 253 # rules are only generated when building with logind. 254 boot.initrd.services.udev.packages = [ (pkgs.runCommand "initrd-plymouth-udev-rules" {} '' 255 mkdir -p $out/etc/udev/rules.d 256 cp ${config.systemd.package.out}/lib/udev/rules.d/{70-uaccess,71-seat}.rules $out/etc/udev/rules.d 257 sed -i '/loginctl/d' $out/etc/udev/rules.d/71-seat.rules 258 '') ]; 259 260 boot.initrd.extraUtilsCommands = lib.mkIf (!config.boot.initrd.systemd.enable) '' 261 copy_bin_and_libs ${plymouth}/bin/plymouth 262 copy_bin_and_libs ${plymouth}/bin/plymouthd 263 264 # Check if the actual requested theme is here 265 if [[ ! -d ${themesEnv}/share/plymouth/themes/${cfg.theme} ]]; then 266 echo "The requested theme: ${cfg.theme} is not provided by any of the packages in boot.plymouth.themePackages" 267 exit 1 268 fi 269 270 moduleName="$(sed -n 's,ModuleName *= *,,p' ${themesEnv}/share/plymouth/themes/${cfg.theme}/${cfg.theme}.plymouth)" 271 272 mkdir -p $out/lib/plymouth/renderers 273 # module might come from a theme 274 cp ${themesEnv}/lib/plymouth/*.so $out/lib/plymouth 275 cp ${plymouth}/lib/plymouth/renderers/*.so $out/lib/plymouth/renderers 276 # useless in the initrd, and adds several megabytes to the closure 277 rm $out/lib/plymouth/renderers/x11.so 278 279 mkdir -p $out/share/plymouth/themes 280 cp ${plymouth}/share/plymouth/plymouthd.defaults $out/share/plymouth 281 282 # Copy themes into working directory for patching 283 mkdir themes 284 285 # Use -L to copy the directories proper, not the symlinks to them. 286 # Copy all themes because they're not large assets, and bgrt depends on the ImageDir of 287 # the spinner theme. 288 cp -r -L ${themesEnv}/share/plymouth/themes/* themes 289 290 # Patch out any attempted references to the theme or plymouth's themes directory 291 chmod -R +w themes 292 find themes -type f | while read file 293 do 294 sed -i "s,${builtins.storeDir}/.*/share/plymouth/themes,$out/share/plymouth/themes,g" $file 295 done 296 297 # Install themes 298 cp -r themes/* $out/share/plymouth/themes 299 300 # Install logo 301 mkdir -p $out/etc/plymouth 302 cp -r -L ${themesEnv}/etc/plymouth $out/etc 303 304 # Setup font 305 mkdir -p $out/share/fonts 306 cp ${cfg.font} $out/share/fonts 307 mkdir -p $out/etc/fonts 308 cat > $out/etc/fonts/fonts.conf <<EOF 309 <?xml version="1.0"?> 310 <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> 311 <fontconfig> 312 <dir>$out/share/fonts</dir> 313 </fontconfig> 314 EOF 315 ''; 316 317 boot.initrd.extraUtilsCommandsTest = mkIf (!config.boot.initrd.systemd.enable) '' 318 $out/bin/plymouthd --help >/dev/null 319 $out/bin/plymouth --help >/dev/null 320 ''; 321 322 boot.initrd.extraUdevRulesCommands = mkIf (!config.boot.initrd.systemd.enable) '' 323 cp ${config.systemd.package}/lib/udev/rules.d/{70-uaccess,71-seat}.rules $out 324 sed -i '/loginctl/d' $out/71-seat.rules 325 ''; 326 327 # We use `mkAfter` to ensure that LUKS password prompt would be shown earlier than the splash screen. 328 boot.initrd.preLVMCommands = mkIf (!config.boot.initrd.systemd.enable) (mkAfter '' 329 mkdir -p /etc/plymouth 330 mkdir -p /run/plymouth 331 ln -s $extraUtils/etc/plymouth/logo.png /etc/plymouth/logo.png 332 ln -s ${configFile} /etc/plymouth/plymouthd.conf 333 ln -s $extraUtils/share/plymouth/plymouthd.defaults /run/plymouth/plymouthd.defaults 334 ln -s $extraUtils/share/plymouth/themes /run/plymouth/themes 335 ln -s $extraUtils/lib/plymouth /run/plymouth/plugins 336 ln -s $extraUtils/etc/fonts /etc/fonts 337 338 plymouthd --mode=boot --pid-file=/run/plymouth/pid --attach-to-session 339 plymouth show-splash 340 ''); 341 342 boot.initrd.postMountCommands = mkIf (!config.boot.initrd.systemd.enable) '' 343 plymouth update-root-fs --new-root-dir="$targetRoot" 344 ''; 345 346 # `mkBefore` to ensure that any custom prompts would be visible. 347 boot.initrd.preFailCommands = mkIf (!config.boot.initrd.systemd.enable) (mkBefore '' 348 plymouth quit --wait 349 ''); 350 351 }; 352 353}