vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / config / console.nix
blob9beb7dc58703406b9765389b197d39321daddebf
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.console;
5   makeColor = i: lib.concatMapStringsSep "," (x: "0x" + lib.substring (2*i) 2 x);
7   isUnicode = lib.hasSuffix "UTF-8" (lib.toUpper config.i18n.defaultLocale);
9   optimizedKeymap = pkgs.runCommand "keymap" {
10     nativeBuildInputs = [ pkgs.buildPackages.kbd ];
11     LOADKEYS_KEYMAP_PATH = "${consoleEnv pkgs.kbd}/share/keymaps/**";
12     preferLocalBuild = true;
13   } ''
14     loadkeys -b ${lib.optionalString isUnicode "-u"} "${cfg.keyMap}" > $out
15   '';
17   # Sadly, systemd-vconsole-setup doesn't support binary keymaps.
18   vconsoleConf = pkgs.writeText "vconsole.conf" ''
19     KEYMAP=${cfg.keyMap}
20     ${lib.optionalString (cfg.font != null) "FONT=${cfg.font}"}
21   '';
23   consoleEnv = kbd: pkgs.buildEnv {
24     name = "console-env";
25     paths = [ kbd ] ++ cfg.packages;
26     pathsToLink = [
27       "/share/consolefonts"
28       "/share/consoletrans"
29       "/share/keymaps"
30       "/share/unimaps"
31     ];
32   };
36   ###### interface
38   options.console  = {
39     enable = lib.mkEnableOption "virtual console" // {
40       default = true;
41     };
43     font = lib.mkOption {
44       type = with lib.types; nullOr (either str path);
45       default = null;
46       example = "LatArCyrHeb-16";
47       description = ''
48         The font used for the virtual consoles.
49         Can be `null`, a font name, or a path to a PSF font file.
51         Use `null` to let the kernel choose a built-in font.
52         The default is 8x16, and, as of Linux 5.3, Terminus 32 bold for display
53         resolutions of 2560x1080 and higher.
54         These fonts cover the [IBM437][] character set.
56         [IBM437]: https://en.wikipedia.org/wiki/Code_page_437
57       '';
58     };
60     keyMap = lib.mkOption {
61       type = with lib.types; either str path;
62       default = "us";
63       example = "fr";
64       description = ''
65         The keyboard mapping table for the virtual consoles.
66       '';
67     };
69     colors = lib.mkOption {
70       type = with lib.types; listOf (strMatching "[[:xdigit:]]{6}");
71       default = [ ];
72       example = [
73         "002b36" "dc322f" "859900" "b58900"
74         "268bd2" "d33682" "2aa198" "eee8d5"
75         "002b36" "cb4b16" "586e75" "657b83"
76         "839496" "6c71c4" "93a1a1" "fdf6e3"
77       ];
78       description = ''
79         The 16 colors palette used by the virtual consoles.
80         Leave empty to use the default colors.
81         Colors must be in hexadecimal format and listed in
82         order from color 0 to color 15.
83       '';
85     };
87     packages = lib.mkOption {
88       type = lib.types.listOf lib.types.package;
89       default = [ ];
90       description = ''
91         List of additional packages that provide console fonts, keymaps and
92         other resources for virtual consoles use.
93       '';
94     };
96     useXkbConfig = lib.mkOption {
97       type = lib.types.bool;
98       default = false;
99       description = ''
100         If set, configure the virtual console keymap from the xserver
101         keyboard settings.
102       '';
103     };
105     earlySetup = lib.mkOption {
106       default = false;
107       type = lib.types.bool;
108       description = ''
109         Enable setting virtual console options as early as possible (in initrd).
110       '';
111     };
113   };
116   ###### implementation
118   config = lib.mkMerge [
119     { console.keyMap = with config.services.xserver;
120         lib.mkIf cfg.useXkbConfig
121           (pkgs.runCommand "xkb-console-keymap" { preferLocalBuild = true; } ''
122             '${pkgs.buildPackages.ckbcomp}/bin/ckbcomp' \
123               ${lib.optionalString (config.environment.sessionVariables ? XKB_CONFIG_ROOT)
124                 "-I${config.environment.sessionVariables.XKB_CONFIG_ROOT}"
125               } \
126               -model '${xkb.model}' -layout '${xkb.layout}' \
127               -option '${xkb.options}' -variant '${xkb.variant}' > "$out"
128           '');
129     }
131     (lib.mkIf (!cfg.enable) {
132       systemd.services = {
133         "serial-getty@ttyS0".enable = false;
134         "serial-getty@hvc0".enable = false;
135         "getty@tty1".enable = false;
136         "autovt@".enable = false;
137         systemd-vconsole-setup.enable = false;
138       };
139     })
141     (lib.mkIf cfg.enable (lib.mkMerge [
142       { environment.systemPackages = [ pkgs.kbd ];
144         # Let systemd-vconsole-setup.service do the work of setting up the
145         # virtual consoles.
146         environment.etc."vconsole.conf".source = vconsoleConf;
147         # Provide kbd with additional packages.
148         environment.etc.kbd.source = "${consoleEnv pkgs.kbd}/share";
150         boot.initrd.preLVMCommands = lib.mkIf (!config.boot.initrd.systemd.enable) (lib.mkBefore ''
151           kbd_mode ${if isUnicode then "-u" else "-a"} -C /dev/console
152           printf "\033%%${if isUnicode then "G" else "@"}" >> /dev/console
153           loadkmap < ${optimizedKeymap}
155           ${lib.optionalString (cfg.earlySetup && cfg.font != null) ''
156             setfont -C /dev/console $extraUtils/share/consolefonts/font.psf
157           ''}
158         '');
160         boot.initrd.systemd.contents = {
161           "/etc/vconsole.conf".source = vconsoleConf;
162           # Add everything if we want full console setup...
163           "/etc/kbd" = lib.mkIf cfg.earlySetup { source = "${consoleEnv config.boot.initrd.systemd.package.kbd}/share"; };
164           # ...but only the keymaps if we don't
165           "/etc/kbd/keymaps" = lib.mkIf (!cfg.earlySetup) { source = "${consoleEnv config.boot.initrd.systemd.package.kbd}/share/keymaps"; };
166         };
167         boot.initrd.systemd.additionalUpstreamUnits = [
168           "systemd-vconsole-setup.service"
169         ];
170         boot.initrd.systemd.storePaths = [
171           "${config.boot.initrd.systemd.package}/lib/systemd/systemd-vconsole-setup"
172           "${config.boot.initrd.systemd.package.kbd}/bin/setfont"
173           "${config.boot.initrd.systemd.package.kbd}/bin/loadkeys"
174           "${config.boot.initrd.systemd.package.kbd.gzip}/bin/gzip" # Fonts and keyboard layouts are compressed
175         ] ++ lib.optionals (cfg.font != null && lib.hasPrefix builtins.storeDir cfg.font) [
176           "${cfg.font}"
177         ] ++ lib.optionals (lib.hasPrefix builtins.storeDir cfg.keyMap) [
178           "${cfg.keyMap}"
179         ];
181         systemd.services.reload-systemd-vconsole-setup =
182           { description = "Reset console on configuration changes";
183             wantedBy = [ "multi-user.target" ];
184             restartTriggers = [ vconsoleConf (consoleEnv pkgs.kbd) ];
185             reloadIfChanged = true;
186             serviceConfig =
187               { RemainAfterExit = true;
188                 ExecStart = "${pkgs.coreutils}/bin/true";
189                 ExecReload = "/run/current-system/systemd/bin/systemctl restart systemd-vconsole-setup";
190               };
191           };
192       }
194       (lib.mkIf (cfg.colors != []) {
195         boot.kernelParams = [
196           "vt.default_red=${makeColor 0 cfg.colors}"
197           "vt.default_grn=${makeColor 1 cfg.colors}"
198           "vt.default_blu=${makeColor 2 cfg.colors}"
199         ];
200       })
202       (lib.mkIf (cfg.earlySetup && cfg.font != null && !config.boot.initrd.systemd.enable) {
203         boot.initrd.extraUtilsCommands = ''
204           mkdir -p $out/share/consolefonts
205           ${if lib.substring 0 1 cfg.font == "/" then ''
206             font="${cfg.font}"
207           '' else ''
208             font="$(echo ${consoleEnv pkgs.kbd}/share/consolefonts/${cfg.font}.*)"
209           ''}
210           if [[ $font == *.gz ]]; then
211             gzip -cd $font > $out/share/consolefonts/font.psf
212           else
213             cp -L $font $out/share/consolefonts/font.psf
214           fi
215         '';
216       })
217     ]))
218   ];
220   imports = [
221     (lib.mkRenamedOptionModule [ "i18n" "consoleFont" ] [ "console" "font" ])
222     (lib.mkRenamedOptionModule [ "i18n" "consoleKeyMap" ] [ "console" "keyMap" ])
223     (lib.mkRenamedOptionModule [ "i18n" "consoleColors" ] [ "console" "colors" ])
224     (lib.mkRenamedOptionModule [ "i18n" "consolePackages" ] [ "console" "packages" ])
225     (lib.mkRenamedOptionModule [ "i18n" "consoleUseXkbConfig" ] [ "console" "useXkbConfig" ])
226     (lib.mkRenamedOptionModule [ "boot" "earlyVconsoleSetup" ] [ "console" "earlySetup" ])
227     (lib.mkRenamedOptionModule [ "boot" "extraTTYs" ] [ "console" "extraTTYs" ])
228     (lib.mkRemovedOptionModule [ "console" "extraTTYs" ] ''
229       Since NixOS switched to systemd (circa 2012), TTYs have been spawned on
230       demand, so there is no need to configure them manually.
231     '')
232   ];