nixos/preload: init
[NixPkgs.git] / nixos / modules / services / wayland / cage.nix
blobcf4c0798cd48bad116229cea3daf418c83f81b77
1 { config, pkgs, lib, ... }:
3 with lib;
5 let
6   cfg = config.services.cage;
7 in {
8   options.services.cage.enable = mkEnableOption (lib.mdDoc "cage kiosk service");
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   };
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   };
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   };
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   };
44   config = mkIf cfg.enable {
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" ];
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;
73         IgnoreSIGPIPE = "no";
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     };
94     security.polkit.enable = true;
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     '';
104     hardware.opengl.enable = mkDefault true;
106     systemd.targets.graphical.wants = [ "cage-tty1.service" ];
108     systemd.defaultUnit = "graphical.target";
109   };
111   meta.maintainers = with lib.maintainers; [ matthewbauer ];