at 17.09-beta 8.7 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.asterisk; 7 8 asteriskUser = "asterisk"; 9 asteriskGroup = "asterisk"; 10 11 varlibdir = "/var/lib/asterisk"; 12 spooldir = "/var/spool/asterisk"; 13 logdir = "/var/log/asterisk"; 14 15 # Add filecontents from files of useTheseDefaultConfFiles to confFiles, do not override 16 defaultConfFiles = subtractLists (attrNames cfg.confFiles) cfg.useTheseDefaultConfFiles; 17 allConfFiles = 18 cfg.confFiles // 19 builtins.listToAttrs (map (x: { name = x; 20 value = builtins.readFile (cfg.package + "/etc/asterisk/" + x); }) 21 defaultConfFiles); 22 23 asteriskEtc = pkgs.stdenv.mkDerivation 24 ((mapAttrs' (name: value: nameValuePair 25 # Fudge the names to make bash happy 26 ((replaceChars ["."] ["_"] name) + "_") 27 (value) 28 ) allConfFiles) // 29 { 30 confFilesString = concatStringsSep " " ( 31 attrNames allConfFiles 32 ); 33 34 name = "asterisk-etc"; 35 36 # Default asterisk.conf file 37 # (Notice that astetcdir will be set to the path of this derivation) 38 asteriskConf = '' 39 [directories] 40 astetcdir => /etc/asterisk 41 astmoddir => ${cfg.package}/lib/asterisk/modules 42 astvarlibdir => /var/lib/asterisk 43 astdbdir => /var/lib/asterisk 44 astkeydir => /var/lib/asterisk 45 astdatadir => /var/lib/asterisk 46 astagidir => /var/lib/asterisk/agi-bin 47 astspooldir => /var/spool/asterisk 48 astrundir => /var/run/asterisk 49 astlogdir => /var/log/asterisk 50 astsbindir => ${cfg.package}/sbin 51 ''; 52 extraConf = cfg.extraConfig; 53 54 # Loading all modules by default is considered sensible by the authors of 55 # "Asterisk: The Definitive Guide". Secure sites will likely want to 56 # specify their own "modules.conf" in the confFiles option. 57 modulesConf = '' 58 [modules] 59 autoload=yes 60 ''; 61 62 # Use syslog for logging so logs can be viewed with journalctl 63 loggerConf = '' 64 [general] 65 66 [logfiles] 67 syslog.local0 => notice,warning,error 68 ''; 69 70 buildCommand = '' 71 mkdir -p "$out" 72 73 # Create asterisk.conf, pointing astetcdir to the path of this derivation 74 echo "$asteriskConf" | sed "s|@out@|$out|g" > "$out"/asterisk.conf 75 echo "$extraConf" >> "$out"/asterisk.conf 76 77 echo "$modulesConf" > "$out"/modules.conf 78 79 echo "$loggerConf" > "$out"/logger.conf 80 81 # Config files specified in confFiles option override all other files 82 for i in $confFilesString; do 83 conf=$(echo "$i"_ | sed 's/\./_/g') 84 echo "''${!conf}" > "$out"/"$i" 85 done 86 ''; 87 }); 88in 89 90{ 91 options = { 92 services.asterisk = { 93 enable = mkOption { 94 type = types.bool; 95 default = false; 96 description = '' 97 Whether to enable the Asterisk PBX server. 98 ''; 99 }; 100 101 extraConfig = mkOption { 102 default = ""; 103 type = types.lines; 104 example = '' 105 [options] 106 verbose=3 107 debug=3 108 ''; 109 description = '' 110 Extra configuration options appended to the default 111 <literal>asterisk.conf</literal> file. 112 ''; 113 }; 114 115 confFiles = mkOption { 116 default = {}; 117 type = types.attrsOf types.str; 118 example = literalExample 119 '' 120 { 121 "extensions.conf" = ''' 122 [tests] 123 ; Dial 100 for "hello, world" 124 exten => 100,1,Answer() 125 same => n,Wait(1) 126 same => n,Playback(hello-world) 127 same => n,Hangup() 128 129 [softphones] 130 include => tests 131 132 [unauthorized] 133 '''; 134 "sip.conf" = ''' 135 [general] 136 allowguest=no ; Require authentication 137 context=unauthorized ; Send unauthorized users to /dev/null 138 srvlookup=no ; Don't do DNS lookup 139 udpbindaddr=0.0.0.0 ; Listen on all interfaces 140 nat=force_rport,comedia ; Assume device is behind NAT 141 142 [softphone](!) 143 type=friend ; Match on username first, IP second 144 context=softphones ; Send to softphones context in 145 ; extensions.conf file 146 host=dynamic ; Device will register with asterisk 147 disallow=all ; Manually specify codecs to allow 148 allow=g722 149 allow=ulaw 150 allow=alaw 151 152 [myphone](softphone) 153 secret=GhoshevFew ; Change this password! 154 '''; 155 "logger.conf" = ''' 156 [general] 157 158 [logfiles] 159 ; Add debug output to log 160 syslog.local0 => notice,warning,error,debug 161 '''; 162 } 163 ''; 164 description = '' 165 Sets the content of config files (typically ending with 166 <literal>.conf</literal>) in the Asterisk configuration directory. 167 168 Note that if you want to change <literal>asterisk.conf</literal>, it 169 is preferable to use the <option>services.asterisk.extraConfig</option> 170 option over this option. If <literal>"asterisk.conf"</literal> is 171 specified with the <option>confFiles</option> option (not recommended), 172 you must be prepared to set your own <literal>astetcdir</literal> 173 path. 174 175 See 176 <link xlink:href="http://www.asterisk.org/community/documentation"/> 177 for more examples of what is possible here. 178 ''; 179 }; 180 181 useTheseDefaultConfFiles = mkOption { 182 default = [ "ari.conf" "acl.conf" "agents.conf" "amd.conf" "calendar.conf" "cdr.conf" "cdr_syslog.conf" "cdr_custom.conf" "cel.conf" "cel_custom.conf" "cli_aliases.conf" "confbridge.conf" "dundi.conf" "features.conf" "hep.conf" "iax.conf" "pjsip.conf" "pjsip_wizard.conf" "phone.conf" "phoneprov.conf" "queues.conf" "res_config_sqlite3.conf" "res_parking.conf" "statsd.conf" "udptl.conf" "unistim.conf" ]; 183 type = types.listOf types.str; 184 example = [ "sip.conf" "dundi.conf" ]; 185 description = ''Sets these config files to the default content. The default value for 186 this option contains all necesscary files to avoid errors at startup. 187 This does not override settings via <option>services.asterisk.confFiles</option>. 188 ''; 189 }; 190 191 extraArguments = mkOption { 192 default = []; 193 type = types.listOf types.str; 194 example = 195 [ "-vvvddd" "-e" "1024" ]; 196 description = '' 197 Additional command line arguments to pass to Asterisk. 198 ''; 199 }; 200 package = mkOption { 201 type = types.package; 202 default = pkgs.asterisk; 203 defaultText = "pkgs.asterisk"; 204 description = "The Asterisk package to use."; 205 }; 206 }; 207 }; 208 209 config = mkIf cfg.enable { 210 environment.systemPackages = [ cfg.package ]; 211 212 environment.etc.asterisk.source = asteriskEtc; 213 214 users.extraUsers.asterisk = 215 { name = asteriskUser; 216 group = asteriskGroup; 217 uid = config.ids.uids.asterisk; 218 description = "Asterisk daemon user"; 219 home = varlibdir; 220 }; 221 222 users.extraGroups.asterisk = 223 { name = asteriskGroup; 224 gid = config.ids.gids.asterisk; 225 }; 226 227 systemd.services.asterisk = { 228 description = '' 229 Asterisk PBX server 230 ''; 231 232 wantedBy = [ "multi-user.target" ]; 233 234 # Do not restart, to avoid disruption of running calls. Restart unit by yourself! 235 restartIfChanged = false; 236 237 preStart = '' 238 # Copy skeleton directory tree to /var 239 for d in '${varlibdir}' '${spooldir}' '${logdir}'; do 240 # TODO: Make exceptions for /var directories that likely should be updated 241 if [ ! -e "$d" ]; then 242 mkdir -p "$d" 243 cp --recursive ${cfg.package}/"$d"/* "$d"/ 244 chown --recursive ${asteriskUser}:${asteriskGroup} "$d" 245 find "$d" -type d | xargs chmod 0755 246 fi 247 done 248 ''; 249 250 serviceConfig = { 251 ExecStart = 252 let 253 # FIXME: This doesn't account for arguments with spaces 254 argString = concatStringsSep " " cfg.extraArguments; 255 in 256 "${cfg.package}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F"; 257 ExecReload = ''${cfg.package}/bin/asterisk -x "core reload" 258 ''; 259 Type = "forking"; 260 PIDFile = "/var/run/asterisk/asterisk.pid"; 261 }; 262 }; 263 }; 264}