mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
nixos/kmscon: RFC42 treatment, support version 10.0.0
This commit includes changes from #483195, #523569, and #523955.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
let
|
||||
@@ -10,8 +11,6 @@ let
|
||||
mkEnableOption
|
||||
mkOption
|
||||
mkPackageOption
|
||||
optional
|
||||
optionals
|
||||
types
|
||||
;
|
||||
|
||||
@@ -22,7 +21,12 @@ let
|
||||
configDir = pkgs.writeTextFile {
|
||||
name = "kmscon-config";
|
||||
destination = "/kmscon.conf";
|
||||
text = cfg.extraConfig;
|
||||
text =
|
||||
let
|
||||
mkKeyValue =
|
||||
k: v: if lib.isBool v then (lib.optionalString (!v) "no-") + k else "${k}=${toString v}";
|
||||
in
|
||||
lib.generators.toKeyValue { inherit mkKeyValue; } (lib.filterAttrs (_: v: v != null) cfg.config);
|
||||
};
|
||||
|
||||
baseLoginOptions = "-p";
|
||||
@@ -55,58 +59,68 @@ in
|
||||
|
||||
Check `services.getty.autologinUser` instead.
|
||||
'')
|
||||
(lib.mkRemovedOptionModule [ "services" "kmscon" "fonts" ] ''
|
||||
`services.kmscon.fonts` is removed.
|
||||
|
||||
Add your font to `fonts.packages` and configure it with
|
||||
`services.kmscon.config.font-name` instead.
|
||||
'')
|
||||
(lib.mkRemovedOptionModule [ "services" "kmscon" "extraConfig" ] ''
|
||||
`services.kmscon.extraConfig` is removed.
|
||||
|
||||
Add your configurations to the new `services.kmscon.config` instead.
|
||||
'')
|
||||
(lib.mkRenamedOptionModule [ "services" "kmscon" "term" ] [ "services" "kmscon" "config" "term" ])
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "kmscon" "hwRender" ]
|
||||
[ "services" "kmscon" "config" "hwaccel" ]
|
||||
)
|
||||
];
|
||||
|
||||
options = {
|
||||
services.kmscon = {
|
||||
enable = mkEnableOption ''
|
||||
Use kmscon instead of autovt.
|
||||
use kmscon instead of autovt.
|
||||
|
||||
Kmscon is a simple terminal emulator based on linux kernel mode setting (KMS).
|
||||
It is an attempt to replace the in-kernel VT implementation with a userspace console.
|
||||
It is an attempt to replace the in-kernel VT implementation with a userspace console
|
||||
'';
|
||||
|
||||
package = mkPackageOption pkgs "kmscon" { };
|
||||
|
||||
hwRender = mkEnableOption "3D hardware acceleration to render the console";
|
||||
useXkbConfig = mkEnableOption ''
|
||||
configure keymap from xserver keyboard settings.
|
||||
|
||||
fonts = mkOption {
|
||||
description = "Fonts used by kmscon, in order of priority.";
|
||||
default = null;
|
||||
example = lib.literalExpression ''[ { name = "Source Code Pro"; package = pkgs.source-code-pro; } ]'';
|
||||
type =
|
||||
with types;
|
||||
let
|
||||
fontType = submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = str;
|
||||
description = "Font name, as used by fontconfig.";
|
||||
};
|
||||
package = mkOption {
|
||||
type = package;
|
||||
description = "Package providing the font.";
|
||||
};
|
||||
};
|
||||
If enabled, configurations under `services.xserver.xkb` will be injected into kmscon's configuration
|
||||
'';
|
||||
|
||||
config = mkOption {
|
||||
description = ''
|
||||
Configuration for kmscon. See {manpage}`kmscon.conf(5)`
|
||||
for available options.
|
||||
'';
|
||||
default = { };
|
||||
type = types.submodule {
|
||||
freeformType =
|
||||
with types;
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
]);
|
||||
options = {
|
||||
hwaccel = mkEnableOption "use hardware acceleration for rendering";
|
||||
libseat = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to use libseat for session management.
|
||||
This is the default for kmscon newer than 10.0.0 and prevents
|
||||
launching another GUI from kmscon by `kmscon-launch-gui`.
|
||||
'';
|
||||
};
|
||||
in
|
||||
nullOr (nonEmptyListOf fontType);
|
||||
};
|
||||
|
||||
useXkbConfig = mkEnableOption "configure keymap from xserver keyboard settings.";
|
||||
|
||||
term = mkOption {
|
||||
description = "Value for the TERM environment variable.";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "xterm-256color";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
description = "Extra contents of the kmscon.conf file.";
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "font-size=14";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
@@ -124,30 +138,54 @@ in
|
||||
assertion = gettyCfg.loginOptions == null;
|
||||
message = "services.getty.loginOptions is not supported when services.kmscon is enabled.";
|
||||
}
|
||||
{
|
||||
assertion = (cfg.config ? font-name) -> config.fonts.fontconfig.enable;
|
||||
message = "Font configuration for kmscon requires fontconfig to be enabled.";
|
||||
}
|
||||
{
|
||||
assertion = cfg.config.hwaccel -> config.hardware.graphics.enable;
|
||||
message = "Hardware acceleration for kmscon requires `hardware.graphics.enable` to be true.";
|
||||
}
|
||||
];
|
||||
|
||||
services.kmscon.config = lib.mkIf cfg.useXkbConfig (
|
||||
lib.mapAttrs (_: lib.mkDefault) (
|
||||
lib.filterAttrs (_: v: v != "") {
|
||||
xkb-layout = config.services.xserver.xkb.layout;
|
||||
xkb-model = config.services.xserver.xkb.model;
|
||||
xkb-options = config.services.xserver.xkb.options;
|
||||
xkb-variant = config.services.xserver.xkb.variant;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
systemd.packages = [ cfg.package ];
|
||||
|
||||
systemd.services."kmsconvt@" = {
|
||||
serviceConfig.ExecStart = [
|
||||
"" # override upstream default with an empty ExecStart
|
||||
(builtins.concatStringsSep " " (
|
||||
[
|
||||
"${cfg.package}/bin/kmscon"
|
||||
"--configdir"
|
||||
configDir
|
||||
"--vt=%I"
|
||||
"--no-switchvt"
|
||||
"--login"
|
||||
]
|
||||
++ lib.optional (cfg.extraOptions != "") cfg.extraOptions
|
||||
++ [
|
||||
"--"
|
||||
loginScript
|
||||
]
|
||||
))
|
||||
];
|
||||
serviceConfig = {
|
||||
User = lib.mkIf (!cfg.config.libseat) "";
|
||||
PAMName = lib.mkIf (!cfg.config.libseat) "";
|
||||
Environment = [ "XKB_CONFIG_ROOT=${config.services.xserver.xkb.dir}" ];
|
||||
ExecStart = [
|
||||
"" # override upstream default with an empty ExecStart
|
||||
(builtins.concatStringsSep " " (
|
||||
[
|
||||
"${cfg.package}/bin/kmscon"
|
||||
"--configdir"
|
||||
configDir
|
||||
"--vt=%I"
|
||||
"--no-switchvt"
|
||||
"--login"
|
||||
]
|
||||
++ lib.optional (cfg.extraOptions != "") cfg.extraOptions
|
||||
++ [
|
||||
"--"
|
||||
loginScript
|
||||
]
|
||||
))
|
||||
];
|
||||
};
|
||||
|
||||
restartIfChanged = false;
|
||||
# logind spawns autovt@ttyN.service on VT switch; point it at kmscon
|
||||
@@ -156,40 +194,55 @@ in
|
||||
|
||||
# tty1 is special: logind does not spawn autovt@tty1, it expects a static
|
||||
# pull-in via getty.target. With getty@ suppressed, we must replace it.
|
||||
systemd.services."getty.target".wants = lib.mkIf (!config.services.displayManager.enable) [
|
||||
systemd.targets.getty.wants = lib.mkIf (!config.services.displayManager.enable) [
|
||||
"kmsconvt@tty1.service"
|
||||
];
|
||||
|
||||
systemd.suppressedSystemUnits = [ "getty@.service" ];
|
||||
|
||||
services.kmscon.extraConfig = lib.concatLines (
|
||||
optionals cfg.useXkbConfig (
|
||||
lib.mapAttrsToList (n: v: "xkb-${n}=${v}") (
|
||||
lib.filterAttrs (
|
||||
n: v:
|
||||
builtins.elem n [
|
||||
"layout"
|
||||
"model"
|
||||
"options"
|
||||
"variant"
|
||||
]
|
||||
&& v != ""
|
||||
) config.services.xserver.xkb
|
||||
)
|
||||
)
|
||||
++ optionals cfg.hwRender [
|
||||
"drm"
|
||||
"hwaccel"
|
||||
]
|
||||
++ optional (cfg.fonts != null) "font-name=${lib.concatMapStringsSep ", " (f: f.name) cfg.fonts}"
|
||||
++ optional (cfg.term != null) "term=${cfg.term}"
|
||||
);
|
||||
|
||||
hardware.graphics.enable = mkIf cfg.hwRender true;
|
||||
|
||||
fonts = mkIf (cfg.fonts != null) {
|
||||
fontconfig.enable = true;
|
||||
packages = map (f: f.package) cfg.fonts;
|
||||
security.pam.services.kmscon = lib.mkIf cfg.config.libseat {
|
||||
useDefaultRules = false;
|
||||
rules = {
|
||||
auth = utils.pam.autoOrderRules [
|
||||
{
|
||||
name = "permit";
|
||||
control = "required";
|
||||
modulePath = "${config.security.pam.package}/lib/security/pam_permit.so";
|
||||
}
|
||||
];
|
||||
account = utils.pam.autoOrderRules [
|
||||
{
|
||||
name = "unix";
|
||||
control = "required";
|
||||
modulePath = "${config.security.pam.package}/lib/security/pam_unix.so";
|
||||
}
|
||||
];
|
||||
session = utils.pam.autoOrderRules [
|
||||
{
|
||||
name = "env";
|
||||
control = "required";
|
||||
modulePath = "${config.security.pam.package}/lib/security/pam_env.so";
|
||||
settings = {
|
||||
conffile = "/etc/pam/environment";
|
||||
readenv = 0;
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "unix";
|
||||
control = "required";
|
||||
modulePath = "${config.security.pam.package}/lib/security/pam_unix.so";
|
||||
}
|
||||
{
|
||||
name = "systemd";
|
||||
control = "optional";
|
||||
modulePath = "${config.systemd.package}/lib/security/pam_systemd.so";
|
||||
settings = {
|
||||
type = "tty";
|
||||
class = "greeter";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -14,17 +14,21 @@
|
||||
|
||||
services.getty.autologinUser = "alice";
|
||||
|
||||
hardware.graphics.enable = true;
|
||||
|
||||
fonts = {
|
||||
fontconfig.enable = true;
|
||||
packages = [ pkgs.nerd-fonts.jetbrains-mono ];
|
||||
};
|
||||
|
||||
services.kmscon = {
|
||||
enable = true;
|
||||
hwRender = true;
|
||||
fonts = [
|
||||
{
|
||||
name = "JetBrainsMono Nerd Font";
|
||||
package = pkgs.nerd-fonts.jetbrains-mono;
|
||||
}
|
||||
];
|
||||
term = "xterm-256color";
|
||||
package = pkgs.kmscon;
|
||||
config = {
|
||||
font-name = "JetBrainsMono Nerd Font";
|
||||
hwaccel = true;
|
||||
term = "kmscon";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -39,7 +43,7 @@
|
||||
machine.send_chars("echo $TERM | tee /tmp/term.txt\n")
|
||||
machine.wait_until_succeeds("test -s /tmp/term.txt")
|
||||
term = machine.succeed("cat /tmp/term.txt").strip()
|
||||
assert term == "xterm-256color", f"Unexpected TERM value: {term!r}"
|
||||
assert term == "kmscon", f"Unexpected TERM value: {term!r}"
|
||||
|
||||
machine.screenshot("tty.png")
|
||||
'';
|
||||
|
||||
Reference in New Issue
Block a user