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