grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / misc / pufferpanel.nix
blob3679d25861e66774a8cf3ce0ff4099d12c3421a4
1 { config, pkgs, lib, ... }:
2 let
3   cfg = config.services.pufferpanel;
4 in
6   options.services.pufferpanel = {
7     enable = lib.mkOption {
8       type = lib.types.bool;
9       default = false;
10       description = ''
11         Whether to enable PufferPanel game management server.
13         Note that [PufferPanel templates] and binaries downloaded by PufferPanel
14         expect [FHS environment]. It is possible to set {option}`package` option
15         to use PufferPanel wrapper with FHS environment. For example, to use
16         `Download Game from Steam` and `Download Java` template operations:
17         ```Nix
18         { lib, pkgs, ... }: {
19           services.pufferpanel = {
20             enable = true;
21             extraPackages = with pkgs; [ bash curl gawk gnutar gzip ];
22             package = pkgs.buildFHSEnv {
23               name = "pufferpanel-fhs";
24               runScript = lib.getExe pkgs.pufferpanel;
25               targetPkgs = pkgs': with pkgs'; [ icu openssl zlib ];
26             };
27           };
28         }
29         ```
31         [PufferPanel templates]: https://github.com/PufferPanel/templates
32         [FHS environment]: https://wikipedia.org/wiki/Filesystem_Hierarchy_Standard
33       '';
34     };
36     package = lib.mkPackageOption pkgs "pufferpanel" { };
38     extraGroups = lib.mkOption {
39       type = lib.types.listOf lib.types.str;
40       default = [ ];
41       example = [ "podman" ];
42       description = ''
43         Additional groups for the systemd service.
44       '';
45     };
47     extraPackages = lib.mkOption {
48       type = lib.types.listOf lib.types.package;
49       default = [ ];
50       example = lib.literalExpression "[ pkgs.jre ]";
51       description = ''
52         Packages to add to the PATH environment variable. Both the {file}`bin`
53         and {file}`sbin` subdirectories of each package are added.
54       '';
55     };
57     environment = lib.mkOption {
58       type = lib.types.attrsOf lib.types.str;
59       default = { };
60       example = lib.literalExpression ''
61         {
62           PUFFER_WEB_HOST = ":8080";
63           PUFFER_DAEMON_SFTP_HOST = ":5657";
64           PUFFER_DAEMON_CONSOLE_BUFFER = "1000";
65           PUFFER_DAEMON_CONSOLE_FORWARD = "true";
66           PUFFER_PANEL_REGISTRATIONENABLED = "false";
67         }
68       '';
69       description = ''
70         Environment variables to set for the service. Secrets should be
71         specified using {option}`environmentFile`.
73         Refer to the [PufferPanel source code][] for the list of available
74         configuration options. Variable name is an upper-cased configuration
75         entry name with underscores instead of dots, prefixed with `PUFFER_`.
76         For example, `panel.settings.companyName` entry can be set using
77         {env}`PUFFER_PANEL_SETTINGS_COMPANYNAME`.
79         When running with panel enabled (configured with `PUFFER_PANEL_ENABLE`
80         environment variable), it is recommended disable registration using
81         `PUFFER_PANEL_REGISTRATIONENABLED` environment variable (registration is
82         enabled by default). To create the initial administrator user, run
83         {command}`pufferpanel --workDir /var/lib/pufferpanel user add --admin`.
85         Some options override corresponding settings set via web interface (e.g.
86         `PUFFER_PANEL_REGISTRATIONENABLED`). Those options can be temporarily
87         toggled or set in settings but do not persist between restarts.
89         [PufferPanel source code]: https://github.com/PufferPanel/PufferPanel/blob/master/config/entries.go
90       '';
91     };
93     environmentFile = lib.mkOption {
94       type = lib.types.nullOr lib.types.path;
95       default = null;
96       description = ''
97         File to load environment variables from. Loaded variables override
98         values set in {option}`environment`.
99       '';
100     };
101   };
103   config = lib.mkIf cfg.enable {
104     systemd.services.pufferpanel = {
105       description = "PufferPanel game management server";
106       wantedBy = [ "multi-user.target" ];
107       after = [ "network.target" ];
109       path = cfg.extraPackages;
110       environment = cfg.environment;
112       # Note that we export environment variables for service directories if the
113       # value is not set. An empty environment variable is considered to be set.
114       # E.g.
115       #   export PUFFER_LOGS=${PUFFER_LOGS-$LOGS_DIRECTORY}
116       # would set PUFFER_LOGS to $LOGS_DIRECTORY if PUFFER_LOGS environment
117       # variable is not defined.
118       script = ''
119         ${lib.concatLines (lib.mapAttrsToList (name: value: ''
120           export ${name}="''${${name}-${value}}"
121         '') {
122           PUFFER_LOGS = "$LOGS_DIRECTORY";
123           PUFFER_DAEMON_DATA_CACHE = "$CACHE_DIRECTORY";
124           PUFFER_DAEMON_DATA_SERVERS = "$STATE_DIRECTORY/servers";
125           PUFFER_DAEMON_DATA_BINARIES = "$STATE_DIRECTORY/binaries";
126         })}
127         exec ${lib.getExe cfg.package} run --workDir "$STATE_DIRECTORY"
128       '';
130       serviceConfig = {
131         Type = "simple";
132         Restart = "always";
134         UMask = "0077";
136         SupplementaryGroups = cfg.extraGroups;
138         StateDirectory = "pufferpanel";
139         StateDirectoryMode = "0700";
140         CacheDirectory = "pufferpanel";
141         CacheDirectoryMode = "0700";
142         LogsDirectory = "pufferpanel";
143         LogsDirectoryMode = "0700";
145         EnvironmentFile = cfg.environmentFile;
147         # Command "pufferpanel shutdown --pid $MAINPID" sends SIGTERM (code 15)
148         # to the main process and waits for termination. This is essentially
149         # KillMode=mixed we are using here. See
150         # https://freedesktop.org/software/systemd/man/systemd.kill.html#KillMode=
151         KillMode = "mixed";
153         DynamicUser = true;
154         ProtectHome = true;
155         ProtectProc = "invisible";
156         ProtectClock = true;
157         ProtectHostname = true;
158         ProtectControlGroups = true;
159         ProtectKernelLogs = true;
160         ProtectKernelModules = true;
161         ProtectKernelTunables = true;
162         PrivateUsers = true;
163         PrivateDevices = true;
164         RestrictRealtime = true;
165         RestrictNamespaces = [ "user" "mnt" ]; # allow buildFHSEnv
166         RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
167         LockPersonality = true;
168         DeviceAllow = [ "" ];
169         DevicePolicy = "closed";
170         CapabilityBoundingSet = [ "" ];
171       };
172     };
173   };
175   meta.maintainers = [ lib.maintainers.tie ];