lol

nixos/spacecookie: convert into settings-style freeform configuration

* Move `hostname` and `root` into a settings submodule with a freeform
type, allowing users to also use options not known to the NixOS
service. Compatibility with a warning for the renamed options is also
trivial to achieve.
* `port` stays where it is as we don't actually use the `port` option of
spacecookie to set up the socket, but only to inform spacecookie about
the port we have set in the `systemd.socket` file, this makes more
sense. Additionally the configuration of the listening port and
address change in the next spacecookie release — we can dodge this
issue altogether by doing our own thing, but I'm interested to hear
opinions on this.
To ensure that this is not misconfigured, we add an assertion for
the port option.
* Add an assertion for `user` in settings which has no effect the way
we are starting spacecookie as it wouldn't be able to call setuid.
The message also explains how a specific user can be used with
spacecookie if desired.

authored by

sternenseemann and committed by
sterni
76583ee8 b74821f3

+75 -23
+71 -21
nixos/modules/services/networking/spacecookie.nix
··· 4 4 5 5 let 6 6 cfg = config.services.spacecookie; 7 - configFile = pkgs.writeText "spacecookie.json" (lib.generators.toJSON {} { 8 - inherit (cfg) hostname port root; 9 - }); 7 + 8 + spacecookieConfig = { 9 + inherit (cfg) port; 10 + } // cfg.settings; 11 + 12 + format = pkgs.formats.json {}; 13 + 14 + configFile = format.generate "spacecookie.json" spacecookieConfig; 15 + 10 16 in { 17 + imports = [ 18 + (mkRenamedOptionModule [ "services" "spacecookie" "root" ] [ "services" "spacecookie" "settings" "root" ]) 19 + (mkRenamedOptionModule [ "services" "spacecookie" "hostname" ] [ "services" "spacecookie" "settings" "hostname" ]) 20 + ]; 11 21 12 22 options = { 13 23 ··· 27 37 ''; 28 38 }; 29 39 30 - hostname = mkOption { 31 - type = types.str; 32 - default = "localhost"; 33 - description = '' 34 - The hostname the service is reachable via. Clients 35 - will use this hostname for further requests after 36 - loading the initial gopher menu. 37 - ''; 38 - }; 39 - 40 40 openFirewall = mkOption { 41 41 type = types.bool; 42 42 default = false; ··· 53 53 ''; 54 54 }; 55 55 56 - root = mkOption { 57 - type = types.path; 58 - default = "/srv/gopher"; 59 - description = '' 60 - The root directory spacecookie serves via gopher. 61 - ''; 62 - }; 63 - 64 56 address = mkOption { 65 57 type = types.str; 66 58 default = "[::]"; ··· 70 62 <link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.socket.html">systemd.socket(5)</link>. 71 63 ''; 72 64 }; 65 + 66 + settings = mkOption { 67 + type = types.submodule { 68 + freeformType = format.type; 69 + 70 + options.hostname = mkOption { 71 + type = types.str; 72 + default = "localhost"; 73 + description = '' 74 + The hostname the service is reachable via. Clients 75 + will use this hostname for further requests after 76 + loading the initial gopher menu. 77 + ''; 78 + }; 79 + 80 + options.root = mkOption { 81 + type = types.path; 82 + default = "/srv/gopher"; 83 + description = '' 84 + The directory spacecookie should serve via gopher. 85 + Files in there need to be world-readable since 86 + the spacecookie service file sets 87 + <literal>DynamicUser=true</literal>. 88 + ''; 89 + }; 90 + }; 91 + 92 + description = '' 93 + Settings for spacecookie. The settings set here are 94 + directly translated to the spacecookie JSON config 95 + file. See the 96 + <link xlink:href="https://github.com/sternenseemann/spacecookie/#configuration">spacecookie documentation</link> 97 + for explanations of all options. 98 + ''; 99 + }; 73 100 }; 74 101 }; 75 102 76 103 config = mkIf cfg.enable { 104 + assertions = [ 105 + { 106 + assertion = !(cfg.settings ? user); 107 + message = '' 108 + spacecookie is started as a normal user, so the setuid 109 + feature doesn't work. If you want to run spacecookie as 110 + a specific user, set: 111 + systemd.services.spacecookie.serviceConfig = { 112 + DynamicUser = false; 113 + User = "youruser"; 114 + Group = "yourgroup"; 115 + } 116 + ''; 117 + } 118 + { 119 + assertion = !(cfg.settings ? port); 120 + message = '' 121 + The NixOS spacecookie module uses socket activation, 122 + so the port option has no effect. Use the port option 123 + in services.spacecookie instead. 124 + ''; 125 + } 126 + ]; 77 127 78 128 systemd.sockets.spacecookie = { 79 129 description = "Socket for the Spacecookie Gopher Server";
+4 -2
nixos/tests/spacecookie.nix
··· 18 18 19 19 services.spacecookie = { 20 20 enable = true; 21 - root = gopherRoot; 22 - hostname = gopherHost; 23 21 openFirewall = true; 22 + settings = { 23 + root = gopherRoot; 24 + hostname = gopherHost; 25 + }; 24 26 }; 25 27 }; 26 28