···1+{ config, pkgs, lib, ... }:
2+with lib;
3+4+let
5+ cfg = config.services.quake3-server;
6+ configFile = pkgs.writeText "q3ds-extra.cfg" ''
7+ set net_port ${builtins.toString cfg.port}
8+9+ ${cfg.extraConfig}
10+ '';
11+ defaultBaseq3 = pkgs.requireFile rec {
12+ name = "baseq3";
13+ hashMode = "recursive";
14+ sha256 = "5dd8ee09eabd45e80450f31d7a8b69b846f59738726929298d8a813ce5725ed3";
15+ message = ''
16+ Unfortunately, we cannot download ${name} automatically.
17+ Please purchase a legitimate copy of Quake 3 and change into the installation directory.
18+19+ You can either add all relevant files to the nix-store like this:
20+ mkdir /tmp/baseq3
21+ cp baseq3/pak*.pk3 /tmp/baseq3
22+ nix-store --add-fixed sha256 --recursive /tmp/baseq3
23+24+ Alternatively you can set services.quake3-server.baseq3 to a path and copy the baseq3 directory into
25+ $services.quake3-server.baseq3/.q3a/
26+ '';
27+ };
28+ home = pkgs.runCommand "quake3-home" {} ''
29+ mkdir -p $out/.q3a/baseq3
30+31+ for file in ${cfg.baseq3}/*; do
32+ ln -s $file $out/.q3a/baseq3/$(basename $file)
33+ done
34+35+ ln -s ${configFile} $out/.q3a/baseq3/nix.cfg
36+ '';
37+in {
38+ options = {
39+ services.quake3-server = {
40+ enable = mkEnableOption "Quake 3 dedicated server";
41+42+ port = mkOption {
43+ type = types.port;
44+ default = 27960;
45+ description = ''
46+ UDP Port the server should listen on.
47+ '';
48+ };
49+50+ openFirewall = mkOption {
51+ type = types.bool;
52+ default = false;
53+ description = ''
54+ Open the firewall.
55+ '';
56+ };
57+58+ extraConfig = mkOption {
59+ type = types.lines;
60+ default = "";
61+ example = ''
62+ seta rconPassword "superSecret" // sets RCON password for remote console
63+ seta sv_hostname "My Quake 3 server" // name that appears in server list
64+ '';
65+ description = ''
66+ Extra configuration options. Note that options changed via RCON will not be persisted. To list all possible
67+ options, use "cvarlist 1" via RCON.
68+ '';
69+ };
70+71+ baseq3 = mkOption {
72+ type = types.either types.package types.path;
73+ default = defaultBaseq3;
74+ example = "/var/lib/q3ds";
75+ description = ''
76+ Path to the baseq3 files (pak*.pk3). If this is on the nix store (type = package) all .pk3 files should be saved
77+ in the top-level directory. If this is on another filesystem (e.g /var/lib/baseq3) the .pk3 files are searched in
78+ $baseq3/.q3a/baseq3/
79+ '';
80+ };
81+ };
82+ };
83+84+ config = let
85+ baseq3InStore = builtins.typeOf cfg.baseq3 == "set";
86+ in mkIf cfg.enable {
87+ networking.firewall.allowedUDPPorts = mkIf cfg.openFirewall [ cfg.port ];
88+89+ systemd.services.q3ds = {
90+ description = "Quake 3 dedicated server";
91+ wantedBy = [ "multi-user.target" ];
92+ after = [ "networking.target" ];
93+94+ environment.HOME = if baseq3InStore then home else cfg.baseq3;
95+96+ serviceConfig = with lib; {
97+ Restart = "always";
98+ DynamicUser = true;
99+ WorkingDirectory = home;
100+101+ # It is possible to alter configuration files via RCON. To ensure reproducibility we have to prevent this
102+ ReadOnlyPaths = if baseq3InStore then home else cfg.baseq3;
103+ ExecStartPre = optionalString (!baseq3InStore) "+${pkgs.coreutils}/bin/cp ${configFile} ${cfg.baseq3}/.q3a/baseq3/nix.cfg";
104+105+ ExecStart = "${pkgs.ioquake3}/ioq3ded.x86_64 +exec nix.cfg";
106+ };
107+ };
108+ };
109+110+ meta.maintainers = with maintainers; [ f4814n ];
111+}
+9-11
nixos/modules/services/misc/home-assistant.nix
···50 # List of components used in config
51 extraComponents = filter useComponent availableComponents;
5253- testedPackage = if (cfg.autoExtraComponents && cfg.config != null)
54 then (cfg.package.override { inherit extraComponents; })
55 else cfg.package;
56-57- # overridePythonAttrs has to be applied after override
58- package = testedPackage.overridePythonAttrs (oldAttrs: {
59- doCheck = false;
60- });
6162 # If you are changing this, please update the description in applyDefaultConfig
63 defaultConfig = {
···188 };
189190 package = mkOption {
191- default = pkgs.home-assistant;
00192 defaultText = literalExample ''
193- pkgs.home-assistant
00194 '';
195 type = types.package;
196 example = literalExample ''
···199 }
200 '';
201 description = ''
202- Home Assistant package to use. Tests are automatically disabled, as they take a considerable amout of time to complete.
203 Override <literal>extraPackages</literal> or <literal>extraComponents</literal> in order to add additional dependencies.
204 If you specify <option>config</option> and do not set <option>autoExtraComponents</option>
205 to <literal>false</literal>, overriding <literal>extraComponents</literal> will have no effect.
206- Avoid <literal>home-assistant.overridePythonAttrs</literal> if you use
207- <literal>autoExtraComponents</literal>.
208 '';
209 };
210
···50 # List of components used in config
51 extraComponents = filter useComponent availableComponents;
5253+ package = if (cfg.autoExtraComponents && cfg.config != null)
54 then (cfg.package.override { inherit extraComponents; })
55 else cfg.package;
000005657 # If you are changing this, please update the description in applyDefaultConfig
58 defaultConfig = {
···183 };
184185 package = mkOption {
186+ default = pkgs.home-assistant.overrideAttrs (oldAttrs: {
187+ doInstallCheck = false;
188+ });
189 defaultText = literalExample ''
190+ pkgs.home-assistant.overrideAttrs (oldAttrs: {
191+ doInstallCheck = false;
192+ })
193 '';
194 type = types.package;
195 example = literalExample ''
···198 }
199 '';
200 description = ''
201+ Home Assistant package to use. By default the tests are disabled, as they take a considerable amout of time to complete.
202 Override <literal>extraPackages</literal> or <literal>extraComponents</literal> in order to add additional dependencies.
203 If you specify <option>config</option> and do not set <option>autoExtraComponents</option>
204 to <literal>false</literal>, overriding <literal>extraComponents</literal> will have no effect.
205+ Avoid <literal>home-assistant.overridePythonAttrs</literal> if you use <literal>autoExtraComponents</literal>.
0206 '';
207 };
208