1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 inherit (pkgs) plymouth;
8
9 cfg = config.boot.plymouth;
10
11 breezePlymouth = pkgs.breeze-plymouth.override {
12 nixosBranding = true;
13 nixosVersion = config.system.nixos.release;
14 };
15
16 themesEnv = pkgs.buildEnv {
17 name = "plymouth-themes";
18 paths = [ plymouth breezePlymouth ] ++ cfg.themePackages;
19 };
20
21 configFile = pkgs.writeText "plymouthd.conf" ''
22 [Daemon]
23 ShowDelay=0
24 Theme=${cfg.theme}
25 '';
26
27in
28
29{
30
31 options = {
32
33 boot.plymouth = {
34
35 enable = mkEnableOption "Plymouth boot splash screen";
36
37 themePackages = mkOption {
38 default = [];
39 type = types.listOf types.package;
40 description = ''
41 Extra theme packages for plymouth.
42 '';
43 };
44
45 theme = mkOption {
46 default = "breeze";
47 type = types.str;
48 description = ''
49 Splash screen theme.
50 '';
51 };
52
53 logo = mkOption {
54 type = types.path;
55 default = pkgs.fetchurl {
56 url = "https://nixos.org/logo/nixos-hires.png";
57 sha256 = "1ivzgd7iz0i06y36p8m5w48fd8pjqwxhdaavc0pxs7w1g7mcy5si";
58 };
59 defaultText = ''pkgs.fetchurl {
60 url = "https://nixos.org/logo/nixos-hires.png";
61 sha256 = "1ivzgd7iz0i06y36p8m5w48fd8pjqwxhdaavc0pxs7w1g7mcy5si";
62 }'';
63 description = ''
64 Logo which is displayed on the splash screen.
65 '';
66 };
67
68 };
69
70 };
71
72 config = mkIf cfg.enable {
73
74 boot.kernelParams = [ "splash" ];
75
76 # To be discoverable by systemd.
77 environment.systemPackages = [ plymouth ];
78
79 environment.etc."plymouth/plymouthd.conf".source = configFile;
80 environment.etc."plymouth/plymouthd.defaults".source = "${plymouth}/share/plymouth/plymouthd.defaults";
81 environment.etc."plymouth/logo.png".source = cfg.logo;
82 environment.etc."plymouth/themes".source = "${themesEnv}/share/plymouth/themes";
83 # XXX: Needed because we supply a different set of plugins in initrd.
84 environment.etc."plymouth/plugins".source = "${plymouth}/lib/plymouth";
85
86 systemd.packages = [ plymouth ];
87
88 systemd.services.plymouth-kexec.wantedBy = [ "kexec.target" ];
89 systemd.services.plymouth-halt.wantedBy = [ "halt.target" ];
90 systemd.services.plymouth-quit = {
91 wantedBy = [ "multi-user.target" ];
92 after = [ "display-manager.service" "multi-user.target" ];
93 };
94 systemd.services.plymouth-poweroff.wantedBy = [ "poweroff.target" ];
95 systemd.services.plymouth-reboot.wantedBy = [ "reboot.target" ];
96 systemd.services.plymouth-read-write.wantedBy = [ "sysinit.target" ];
97
98 boot.initrd.extraUtilsCommands = ''
99 copy_bin_and_libs ${pkgs.plymouth}/bin/plymouthd
100 copy_bin_and_libs ${pkgs.plymouth}/bin/plymouth
101
102 moduleName="$(sed -n 's,ModuleName *= *,,p' ${themesEnv}/share/plymouth/themes/${cfg.theme}/${cfg.theme}.plymouth)"
103
104 mkdir -p $out/lib/plymouth/renderers
105 # module might come from a theme
106 cp ${themesEnv}/lib/plymouth/{text,details,$moduleName}.so $out/lib/plymouth
107 cp ${plymouth}/lib/plymouth/renderers/{drm,frame-buffer}.so $out/lib/plymouth/renderers
108
109 mkdir -p $out/share/plymouth/themes
110 cp ${plymouth}/share/plymouth/plymouthd.defaults $out/share/plymouth
111
112 # copy themes into working directory for patching
113 mkdir themes
114 # use -L to copy the directories proper, not the symlinks to them
115 cp -r -L ${themesEnv}/share/plymouth/themes/{text,details,${cfg.theme}} themes
116
117 # patch out any attempted references to the theme or plymouth's themes directory
118 chmod -R +w themes
119 find themes -type f | while read file
120 do
121 sed -i "s,/nix/.*/share/plymouth/themes,$out/share/plymouth/themes,g" $file
122 done
123
124 cp -r themes/* $out/share/plymouth/themes
125 cp ${cfg.logo} $out/share/plymouth/logo.png
126 '';
127
128 boot.initrd.extraUtilsCommandsTest = ''
129 $out/bin/plymouthd --help >/dev/null
130 $out/bin/plymouth --help >/dev/null
131 '';
132
133 boot.initrd.extraUdevRulesCommands = ''
134 cp ${config.systemd.package}/lib/udev/rules.d/{70-uaccess,71-seat}.rules $out
135 sed -i '/loginctl/d' $out/71-seat.rules
136 '';
137
138 # We use `mkAfter` to ensure that LUKS password prompt would be shown earlier than the splash screen.
139 boot.initrd.preLVMCommands = mkAfter ''
140 mkdir -p /etc/plymouth
141 ln -s ${configFile} /etc/plymouth/plymouthd.conf
142 ln -s $extraUtils/share/plymouth/plymouthd.defaults /etc/plymouth/plymouthd.defaults
143 ln -s $extraUtils/share/plymouth/logo.png /etc/plymouth/logo.png
144 ln -s $extraUtils/share/plymouth/themes /etc/plymouth/themes
145 ln -s $extraUtils/lib/plymouth /etc/plymouth/plugins
146
147 plymouthd --mode=boot --pid-file=/run/plymouth/pid --attach-to-session
148 plymouth show-splash
149 '';
150
151 boot.initrd.postMountCommands = ''
152 plymouth update-root-fs --new-root-dir="$targetRoot"
153 '';
154
155 # `mkBefore` to ensure that any custom prompts would be visible.
156 boot.initrd.preFailCommands = mkBefore ''
157 plymouth quit --wait
158 '';
159
160 };
161
162}