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