at 23.11-beta 3.3 kB view raw
1{ config, pkgs, lib, ... }: 2 3with lib; 4 5let 6 cfg = config.services.cage; 7in { 8 options.services.cage.enable = mkEnableOption (lib.mdDoc "cage kiosk service"); 9 10 options.services.cage.user = mkOption { 11 type = types.str; 12 default = "demo"; 13 description = lib.mdDoc '' 14 User to log-in as. 15 ''; 16 }; 17 18 options.services.cage.extraArguments = mkOption { 19 type = types.listOf types.str; 20 default = []; 21 defaultText = literalExpression "[]"; 22 description = lib.mdDoc "Additional command line arguments to pass to Cage."; 23 example = ["-d"]; 24 }; 25 26 options.services.cage.environment = mkOption { 27 type = types.attrsOf types.str; 28 default = {}; 29 example = { 30 WLR_LIBINPUT_NO_DEVICES = "1"; 31 }; 32 description = lib.mdDoc "Additional environment variables to pass to Cage."; 33 }; 34 35 options.services.cage.program = mkOption { 36 type = types.path; 37 default = "${pkgs.xterm}/bin/xterm"; 38 defaultText = literalExpression ''"''${pkgs.xterm}/bin/xterm"''; 39 description = lib.mdDoc '' 40 Program to run in cage. 41 ''; 42 }; 43 44 config = mkIf cfg.enable { 45 46 # The service is partially based off of the one provided in the 47 # cage wiki at 48 # https://github.com/Hjdskes/cage/wiki/Starting-Cage-on-boot-with-systemd. 49 systemd.services."cage-tty1" = { 50 enable = true; 51 after = [ 52 "systemd-user-sessions.service" 53 "plymouth-start.service" 54 "plymouth-quit.service" 55 "systemd-logind.service" 56 "getty@tty1.service" 57 ]; 58 before = [ "graphical.target" ]; 59 wants = [ "dbus.socket" "systemd-logind.service" "plymouth-quit.service"]; 60 wantedBy = [ "graphical.target" ]; 61 conflicts = [ "getty@tty1.service" ]; 62 63 restartIfChanged = false; 64 unitConfig.ConditionPathExists = "/dev/tty1"; 65 serviceConfig = { 66 ExecStart = '' 67 ${pkgs.cage}/bin/cage \ 68 ${escapeShellArgs cfg.extraArguments} \ 69 -- ${cfg.program} 70 ''; 71 User = cfg.user; 72 73 IgnoreSIGPIPE = "no"; 74 75 # Log this user with utmp, letting it show up with commands 'w' and 76 # 'who'. This is needed since we replace (a)getty. 77 UtmpIdentifier = "%n"; 78 UtmpMode = "user"; 79 # A virtual terminal is needed. 80 TTYPath = "/dev/tty1"; 81 TTYReset = "yes"; 82 TTYVHangup = "yes"; 83 TTYVTDisallocate = "yes"; 84 # Fail to start if not controlling the virtual terminal. 85 StandardInput = "tty-fail"; 86 StandardOutput = "journal"; 87 StandardError = "journal"; 88 # Set up a full (custom) user session for the user, required by Cage. 89 PAMName = "cage"; 90 }; 91 environment = cfg.environment; 92 }; 93 94 security.polkit.enable = true; 95 96 security.pam.services.cage.text = '' 97 auth required pam_unix.so nullok 98 account required pam_unix.so 99 session required pam_unix.so 100 session required pam_env.so conffile=/etc/pam/environment readenv=0 101 session required ${config.systemd.package}/lib/security/pam_systemd.so 102 ''; 103 104 hardware.opengl.enable = mkDefault true; 105 106 systemd.targets.graphical.wants = [ "cage-tty1.service" ]; 107 108 systemd.defaultUnit = "graphical.target"; 109 }; 110 111 meta.maintainers = with lib.maintainers; [ matthewbauer ]; 112 113}