1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 settingsFormat = {
7 type = with lib.types; attrsOf (oneOf [ bool int str ]);
8 generate = name: attrs:
9 pkgs.writeText name (lib.strings.concatStringsSep "\n"
10 (lib.attrsets.mapAttrsToList
11 (key: value: "${key}=${builtins.toJSON value}") attrs));
12 };
13in {
14 options = {
15
16 services.uhub = mkOption {
17 default = { };
18 description = lib.mdDoc "Uhub ADC hub instances";
19 type = types.attrsOf (types.submodule {
20 options = {
21
22 enable = mkEnableOption (lib.mdDoc "hub instance") // { default = true; };
23
24 enableTLS = mkOption {
25 type = types.bool;
26 default = false;
27 description = lib.mdDoc "Whether to enable TLS support.";
28 };
29
30 settings = mkOption {
31 inherit (settingsFormat) type;
32 description = lib.mdDoc ''
33 Configuration of uhub.
34 See https://www.uhub.org/doc/config.php for a list of options.
35 '';
36 default = { };
37 example = {
38 server_bind_addr = "any";
39 server_port = 1511;
40 hub_name = "My Public Hub";
41 hub_description = "Yet another ADC hub";
42 max_users = 150;
43 };
44 };
45
46 plugins = mkOption {
47 description = lib.mdDoc "Uhub plugin configuration.";
48 type = with types;
49 listOf (submodule {
50 options = {
51 plugin = mkOption {
52 type = path;
53 example = literalExpression
54 "$${pkgs.uhub}/plugins/mod_auth_sqlite.so";
55 description = lib.mdDoc "Path to plugin file.";
56 };
57 settings = mkOption {
58 description = lib.mdDoc "Settings specific to this plugin.";
59 type = with types; attrsOf str;
60 example = { file = "/etc/uhub/users.db"; };
61 };
62 };
63 });
64 default = [ ];
65 };
66
67 };
68 });
69 };
70
71 };
72
73 config = let
74 hubs = lib.attrsets.filterAttrs (_: cfg: cfg.enable) config.services.uhub;
75 in {
76
77 environment.etc = lib.attrsets.mapAttrs' (name: cfg:
78 let
79 settings' = cfg.settings // {
80 tls_enable = cfg.enableTLS;
81 file_plugins = pkgs.writeText "uhub-plugins.conf"
82 (lib.strings.concatStringsSep "\n" (map ({ plugin, settings }:
83 ''
84 plugin ${plugin} "${
85 toString
86 (lib.attrsets.mapAttrsToList (key: value: "${key}=${value}")
87 settings)
88 }"'') cfg.plugins));
89 };
90 in {
91 name = "uhub/${name}.conf";
92 value.source = settingsFormat.generate "uhub-${name}.conf" settings';
93 }) hubs;
94
95 systemd.services = lib.attrsets.mapAttrs' (name: cfg: {
96 name = "uhub-${name}";
97 value = let pkg = pkgs.uhub.override { tlsSupport = cfg.enableTLS; };
98 in {
99 description = "high performance peer-to-peer hub for the ADC network";
100 after = [ "network.target" ];
101 wantedBy = [ "multi-user.target" ];
102 reloadIfChanged = true;
103 serviceConfig = {
104 Type = "notify";
105 ExecStart = "${pkg}/bin/uhub -c /etc/uhub/${name}.conf -L";
106 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
107 DynamicUser = true;
108
109 AmbientCapabilities = "CAP_NET_BIND_SERVICE";
110 CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";
111 };
112 };
113 }) hubs;
114 };
115
116}