1 { config, lib, pkgs, ... }:
6 cfg = config.services.asterisk;
8 asteriskUser = "asterisk";
9 asteriskGroup = "asterisk";
11 varlibdir = "/var/lib/asterisk";
12 spooldir = "/var/spool/asterisk";
13 logdir = "/var/log/asterisk";
15 # Add filecontents from files of useTheseDefaultConfFiles to confFiles, do not override
16 defaultConfFiles = subtractLists (attrNames cfg.confFiles) cfg.useTheseDefaultConfFiles;
18 # Default asterisk.conf file
19 "asterisk.conf".text = ''
21 astetcdir => /etc/asterisk
22 astmoddir => ${cfg.package}/lib/asterisk/modules
23 astvarlibdir => /var/lib/asterisk
24 astdbdir => /var/lib/asterisk
25 astkeydir => /var/lib/asterisk
26 astdatadir => /var/lib/asterisk
27 astagidir => /var/lib/asterisk/agi-bin
28 astspooldir => /var/spool/asterisk
29 astrundir => /run/asterisk
30 astlogdir => /var/log/asterisk
31 astsbindir => ${cfg.package}/sbin
35 # Loading all modules by default is considered sensible by the authors of
36 # "Asterisk: The Definitive Guide". Secure sites will likely want to
37 # specify their own "modules.conf" in the confFiles option.
38 "modules.conf".text = ''
43 # Use syslog for logging so logs can be viewed with journalctl
44 "logger.conf".text = ''
48 syslog.local0 => notice,warning,error
51 mapAttrs (name: text: { inherit text; }) cfg.confFiles //
52 listToAttrs (map (x: nameValuePair x { source = cfg.package + "/etc/asterisk/" + x; }) defaultConfFiles);
62 description = lib.mdDoc ''
63 Whether to enable the Asterisk PBX server.
67 extraConfig = mkOption {
75 description = lib.mdDoc ''
76 Extra configuration options appended to the default
81 confFiles = mkOption {
83 type = types.attrsOf types.str;
84 example = literalExpression
87 "extensions.conf" = '''
89 ; Dial 100 for "hello, world"
90 exten => 100,1,Answer()
92 same => n,Playback(hello-world)
102 allowguest=no ; Require authentication
103 context=unauthorized ; Send unauthorized users to /dev/null
104 srvlookup=no ; Don't do DNS lookup
105 udpbindaddr=0.0.0.0 ; Listen on all interfaces
106 nat=force_rport,comedia ; Assume device is behind NAT
109 type=friend ; Match on username first, IP second
110 context=softphones ; Send to softphones context in
111 ; extensions.conf file
112 host=dynamic ; Device will register with asterisk
113 disallow=all ; Manually specify codecs to allow
119 secret=GhoshevFew ; Change this password!
125 ; Add debug output to log
126 syslog.local0 => notice,warning,error,debug
130 description = lib.mdDoc ''
131 Sets the content of config files (typically ending with
132 `.conf`) in the Asterisk configuration directory.
134 Note that if you want to change `asterisk.conf`, it
135 is preferable to use the {option}`services.asterisk.extraConfig`
136 option over this option. If `"asterisk.conf"` is
137 specified with the {option}`confFiles` option (not recommended),
138 you must be prepared to set your own `astetcdir`
142 <http://www.asterisk.org/community/documentation>
143 for more examples of what is possible here.
147 useTheseDefaultConfFiles = mkOption {
148 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" ];
149 type = types.listOf types.str;
150 example = [ "sip.conf" "dundi.conf" ];
151 description = lib.mdDoc ''Sets these config files to the default content. The default value for
152 this option contains all necesscary files to avoid errors at startup.
153 This does not override settings via {option}`services.asterisk.confFiles`.
157 extraArguments = mkOption {
159 type = types.listOf types.str;
161 [ "-vvvddd" "-e" "1024" ];
162 description = lib.mdDoc ''
163 Additional command line arguments to pass to Asterisk.
167 type = types.package;
168 default = pkgs.asterisk;
169 defaultText = literalExpression "pkgs.asterisk";
170 description = lib.mdDoc "The Asterisk package to use.";
175 config = mkIf cfg.enable {
176 environment.systemPackages = [ cfg.package ];
178 environment.etc = mapAttrs' (name: value:
179 nameValuePair "asterisk/${name}" value
182 users.users.asterisk =
183 { name = asteriskUser;
184 group = asteriskGroup;
185 uid = config.ids.uids.asterisk;
186 description = "Asterisk daemon user";
190 users.groups.asterisk =
191 { name = asteriskGroup;
192 gid = config.ids.gids.asterisk;
195 systemd.services.asterisk = {
200 wantedBy = [ "multi-user.target" ];
202 # Do not restart, to avoid disruption of running calls. Restart unit by yourself!
203 restartIfChanged = false;
206 # Copy skeleton directory tree to /var
207 for d in '${varlibdir}' '${spooldir}' '${logdir}'; do
208 # TODO: Make exceptions for /var directories that likely should be updated
209 if [ ! -e "$d" ]; then
211 cp --recursive ${cfg.package}/"$d"/* "$d"/
212 chown --recursive ${asteriskUser}:${asteriskGroup} "$d"
213 find "$d" -type d | xargs chmod 0755
221 # FIXME: This doesn't account for arguments with spaces
222 argString = concatStringsSep " " cfg.extraArguments;
224 "${cfg.package}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F";
225 ExecReload = ''${cfg.package}/bin/asterisk -x "core reload"
228 PIDFile = "/run/asterisk/asterisk.pid";