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-wait.wantedBy = [ "multi-user.target" ];
91 systemd.services.plymouth-quit = {
92 wantedBy = [ "multi-user.target" ];
93 after = [ "display-manager.service" ];
94 };
95 systemd.services.plymouth-poweroff.wantedBy = [ "poweroff.target" ];
96 systemd.services.plymouth-reboot.wantedBy = [ "reboot.target" ];
97 systemd.services.plymouth-read-write.wantedBy = [ "sysinit.target" ];
98
99 boot.initrd.extraUtilsCommands = ''
100 copy_bin_and_libs ${pkgs.plymouth}/bin/plymouthd
101 copy_bin_and_libs ${pkgs.plymouth}/bin/plymouth
102
103 moduleName="$(sed -n 's,ModuleName *= *,,p' ${themesEnv}/share/plymouth/themes/${cfg.theme}/${cfg.theme}.plymouth)"
104
105 mkdir -p $out/lib/plymouth/renderers
106 # module might come from a theme
107 cp ${themesEnv}/lib/plymouth/{text,details,$moduleName}.so $out/lib/plymouth
108 cp ${plymouth}/lib/plymouth/renderers/{drm,frame-buffer}.so $out/lib/plymouth/renderers
109
110 mkdir -p $out/share/plymouth/themes
111 cp ${plymouth}/share/plymouth/plymouthd.defaults $out/share/plymouth
112
113 # copy themes into working directory for patching
114 mkdir themes
115 # use -L to copy the directories proper, not the symlinks to them
116 cp -r -L ${themesEnv}/share/plymouth/themes/{text,details,${cfg.theme}} themes
117
118 # patch out any attempted references to the theme or plymouth's themes directory
119 chmod -R +w themes
120 find themes -type f | while read file
121 do
122 sed -i "s,/nix/.*/share/plymouth/themes,$out/share/plymouth/themes,g" $file
123 done
124
125 cp -r themes/* $out/share/plymouth/themes
126 cp ${cfg.logo} $out/share/plymouth/logo.png
127 '';
128
129 boot.initrd.extraUtilsCommandsTest = ''
130 $out/bin/plymouthd --help >/dev/null
131 $out/bin/plymouth --help >/dev/null
132 '';
133
134 boot.initrd.extraUdevRulesCommands = ''
135 cp ${config.systemd.package}/lib/udev/rules.d/{70-uaccess,71-seat}.rules $out
136 sed -i '/loginctl/d' $out/71-seat.rules
137 '';
138
139 # We use `mkAfter` to ensure that LUKS password prompt would be shown earlier than the splash screen.
140 boot.initrd.preLVMCommands = mkAfter ''
141 mkdir -p /etc/plymouth
142 ln -s ${configFile} /etc/plymouth/plymouthd.conf
143 ln -s $extraUtils/share/plymouth/plymouthd.defaults /etc/plymouth/plymouthd.defaults
144 ln -s $extraUtils/share/plymouth/logo.png /etc/plymouth/logo.png
145 ln -s $extraUtils/share/plymouth/themes /etc/plymouth/themes
146 ln -s $extraUtils/lib/plymouth /etc/plymouth/plugins
147
148 plymouthd --mode=boot --pid-file=/run/plymouth/pid --attach-to-session
149 plymouth show-splash
150 '';
151
152 boot.initrd.postMountCommands = ''
153 plymouth update-root-fs --new-root-dir="$targetRoot"
154 '';
155
156 # `mkBefore` to ensure that any custom prompts would be visible.
157 boot.initrd.preFailCommands = mkBefore ''
158 plymouth quit --wait
159 '';
160
161 };
162
163}