at 25.11-pre 4.5 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10let 11 cfg = config.services.soju; 12 stateDir = "/var/lib/soju"; 13 runtimeDir = "/run/soju"; 14 listen = cfg.listen ++ optional cfg.adminSocket.enable "unix+admin://${runtimeDir}/admin"; 15 listenCfg = concatMapStringsSep "\n" (l: "listen ${l}") listen; 16 tlsCfg = optionalString ( 17 cfg.tlsCertificate != null 18 ) "tls ${cfg.tlsCertificate} ${cfg.tlsCertificateKey}"; 19 logCfg = optionalString cfg.enableMessageLogging "message-store fs ${stateDir}/logs"; 20 21 configFile = pkgs.writeText "soju.conf" '' 22 ${listenCfg} 23 hostname ${cfg.hostName} 24 ${tlsCfg} 25 db sqlite3 ${stateDir}/soju.db 26 ${logCfg} 27 http-origin ${concatStringsSep " " cfg.httpOrigins} 28 accept-proxy-ip ${concatStringsSep " " cfg.acceptProxyIP} 29 30 ${cfg.extraConfig} 31 ''; 32 33 sojuctl = pkgs.writeShellScriptBin "sojuctl" '' 34 exec ${lib.getExe' cfg.package "sojuctl"} --config ${cfg.configFile} "$@" 35 ''; 36in 37{ 38 ###### interface 39 40 options.services.soju = { 41 enable = mkEnableOption "soju"; 42 43 package = mkPackageOption pkgs "soju" { }; 44 45 listen = mkOption { 46 type = types.listOf types.str; 47 default = [ ":6697" ]; 48 description = '' 49 Where soju should listen for incoming connections. See the 50 `listen` directive in 51 {manpage}`soju(1)`. 52 ''; 53 }; 54 55 hostName = mkOption { 56 type = types.str; 57 default = config.networking.hostName; 58 defaultText = literalExpression "config.networking.hostName"; 59 description = "Server hostname."; 60 }; 61 62 tlsCertificate = mkOption { 63 type = types.nullOr types.path; 64 default = null; 65 example = "/var/host.cert"; 66 description = "Path to server TLS certificate."; 67 }; 68 69 tlsCertificateKey = mkOption { 70 type = types.nullOr types.path; 71 default = null; 72 example = "/var/host.key"; 73 description = "Path to server TLS certificate key."; 74 }; 75 76 enableMessageLogging = mkOption { 77 type = types.bool; 78 default = true; 79 description = "Whether to enable message logging."; 80 }; 81 82 adminSocket.enable = mkOption { 83 type = types.bool; 84 default = true; 85 description = '' 86 Listen for admin connections from sojuctl at /run/soju/admin. 87 ''; 88 }; 89 90 httpOrigins = mkOption { 91 type = types.listOf types.str; 92 default = [ ]; 93 description = '' 94 List of allowed HTTP origins for WebSocket listeners. The parameters are 95 interpreted as shell patterns, see 96 {manpage}`glob(7)`. 97 ''; 98 }; 99 100 acceptProxyIP = mkOption { 101 type = types.listOf types.str; 102 default = [ ]; 103 description = '' 104 Allow the specified IPs to act as a proxy. Proxys have the ability to 105 overwrite the remote and local connection addresses (via the X-Forwarded-\* 106 HTTP header fields). The special name "localhost" accepts the loopback 107 addresses 127.0.0.0/8 and ::1/128. By default, all IPs are rejected. 108 ''; 109 }; 110 111 extraConfig = mkOption { 112 type = types.lines; 113 default = ""; 114 description = "Lines added verbatim to the generated configuration file."; 115 }; 116 117 configFile = mkOption { 118 type = types.path; 119 default = configFile; 120 defaultText = "Config file generated from other options."; 121 description = '' 122 Path to config file. If this option is set, it will override any 123 configuration done using other options, including {option}`extraConfig`. 124 ''; 125 example = literalExpression "./soju.conf"; 126 }; 127 }; 128 129 ###### implementation 130 131 config = mkIf cfg.enable { 132 assertions = [ 133 { 134 assertion = (cfg.tlsCertificate != null) == (cfg.tlsCertificateKey != null); 135 message = '' 136 services.soju.tlsCertificate and services.soju.tlsCertificateKey 137 must both be specified to enable TLS. 138 ''; 139 } 140 ]; 141 142 environment.systemPackages = [ sojuctl ]; 143 144 systemd.services.soju = { 145 description = "soju IRC bouncer"; 146 wantedBy = [ "multi-user.target" ]; 147 wants = [ "network-online.target" ]; 148 after = [ "network-online.target" ]; 149 documentation = [ "man:soju(1)" ]; 150 serviceConfig = { 151 DynamicUser = true; 152 Restart = "always"; 153 ExecStart = "${lib.getExe' cfg.package "soju"} -config ${cfg.configFile}"; 154 StateDirectory = "soju"; 155 RuntimeDirectory = "soju"; 156 }; 157 }; 158 }; 159 160 meta.maintainers = with maintainers; [ malte-v ]; 161}