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