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