Added NixOS module for Asterisk server

Changed files
+226
nixos
modules
misc
services
networking
+2
nixos/modules/misc/ids.nix
···
ihaskell = 189;
i2p = 190;
lambdabot = 191;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
···
ihaskell = 189;
i2p = 190;
lambdabot = 191;
# When adding a gid, make sure it doesn't match an existing
# uid. Users and groups with the same name should have equal
···
ihaskell = 189;
i2p = 190;
lambdabot = 191;
+
asterisk = 192;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
···
ihaskell = 189;
i2p = 190;
lambdabot = 191;
+
#asterisk = 192; # unused
# When adding a gid, make sure it doesn't match an existing
# uid. Users and groups with the same name should have equal
+1
nixos/modules/module-list.nix
···
./services/network-filesystems/yandex-disk.nix
./services/networking/aiccu.nix
./services/networking/amuled.nix
./services/networking/atftpd.nix
./services/networking/avahi-daemon.nix
./services/networking/bind.nix
···
./services/network-filesystems/yandex-disk.nix
./services/networking/aiccu.nix
./services/networking/amuled.nix
+
./services/networking/asterisk.nix
./services/networking/atftpd.nix
./services/networking/avahi-daemon.nix
./services/networking/bind.nix
+223
nixos/modules/services/networking/asterisk.nix
···
···
+
{ config, lib, pkgs, ... }:
+
+
with lib;
+
+
let
+
cfg = config.services.asterisk;
+
+
asteriskUser = "asterisk";
+
+
varlibdir = "/var/lib/asterisk";
+
spooldir = "/var/spool/asterisk";
+
logdir = "/var/log/asterisk";
+
+
asteriskEtc = pkgs.stdenv.mkDerivation
+
((mapAttrs' (name: value: nameValuePair
+
# Fudge the names to make bash happy
+
((replaceChars ["."] ["_"] name) + "_")
+
(value)
+
) cfg.confFiles) //
+
{
+
confFilesString = concatStringsSep " " (
+
attrNames cfg.confFiles
+
);
+
+
name = "asterisk.etc";
+
+
# Default asterisk.conf file
+
# (Notice that astetcdir will be set to the path of this derivation)
+
asteriskConf = ''
+
[directories]
+
astetcdir => @out@
+
astmoddir => ${pkgs.asterisk}/lib/asterisk/modules
+
astvarlibdir => /var/lib/asterisk
+
astdbdir => /var/lib/asterisk
+
astkeydir => /var/lib/asterisk
+
astdatadir => /var/lib/asterisk
+
astagidir => /var/lib/asterisk/agi-bin
+
astspooldir => /var/spool/asterisk
+
astrundir => /var/run/asterisk
+
astlogdir => /var/log/asterisk
+
astsbindir => ${pkgs.asterisk}/sbin
+
'';
+
extraConf = cfg.extraConfig;
+
+
# Loading all modules by default is considered sensible by the authors of
+
# "Asterisk: The Definitive Guide". Secure sites will likely want to
+
# specify their own "modules.conf" in the confFiles option.
+
modulesConf = ''
+
[modules]
+
autoload=yes
+
'';
+
+
# Use syslog for logging so logs can be viewed with journalctl
+
loggerConf = ''
+
[general]
+
+
[logfiles]
+
syslog.local0 => notice,warning,error
+
'';
+
+
buildCommand = ''
+
mkdir -p "$out"
+
+
# Create asterisk.conf, pointing astetcdir to the path of this derivation
+
echo "$asteriskConf" | sed "s|@out@|$out|g" > "$out"/asterisk.conf
+
echo "$extraConf" >> "$out"/asterisk.conf
+
+
echo "$modulesConf" > "$out"/modules.conf
+
+
echo "$loggerConf" > "$out"/logger.conf
+
+
# Config files specified in confFiles option override all other files
+
for i in $confFilesString; do
+
conf=$(echo "$i"_ | sed 's/\./_/g')
+
echo "''${!conf}" > "$out"/"$i"
+
done
+
'';
+
});
+
in
+
+
{
+
options = {
+
services.asterisk = {
+
enable = mkOption {
+
type = types.bool;
+
default = false;
+
description = ''
+
Whether to enable the Asterisk PBX server.
+
'';
+
};
+
+
extraConfig = mkOption {
+
default = "";
+
type = types.lines;
+
example = ''
+
[options]
+
verbose=3
+
debug=3
+
'';
+
description = ''
+
Extra configuration options appended to the default
+
<literal>asterisk.conf</literal> file.
+
'';
+
};
+
+
confFiles = mkOption {
+
default = {};
+
type = types.attrsOf types.str;
+
example = literalExample
+
''
+
{
+
"extensions.conf" = '''
+
[tests]
+
; Dial 100 for "hello, world"
+
exten => 100,1,Answer()
+
same => n,Wait(1)
+
same => n,Playback(hello-world)
+
same => n,Hangup()
+
+
[softphones]
+
include => tests
+
+
[unauthorized]
+
''';
+
"sip.conf" = '''
+
[general]
+
allowguest=no ; Require authentication
+
context=unauthorized ; Send unauthorized users to /dev/null
+
srvlookup=no ; Don't do DNS lookup
+
udpbindaddr=0.0.0.0 ; Listen on all interfaces
+
nat=force_rport,comedia ; Assume device is behind NAT
+
+
[softphone](!)
+
type=friend ; Match on username first, IP second
+
context=softphones ; Send to softphones context in
+
; extensions.conf file
+
host=dynamic ; Device will register with asterisk
+
disallow=all ; Manually specify codecs to allow
+
allow=g722
+
allow=ulaw
+
allow=alaw
+
+
[myphone](softphone)
+
secret=GhoshevFew ; Change this password!
+
''';
+
"logger.conf" = '''
+
[general]
+
+
[logfiles]
+
; Add debug output to log
+
syslog.local0 => notice,warning,error,debug
+
''';
+
}
+
'';
+
description = ''
+
Sets the content of config files (typically ending with
+
<literal>.conf</literal>) in the Asterisk configuration directory.
+
+
Note that if you want to change <literal>asterisk.conf</literal>, it
+
is preferable to use the <option>services.asterisk.extraConfig</option>
+
option over this option. If <literal>"asterisk.conf"</literal> is
+
specified with the <option>confFiles</option> option (not recommended),
+
you must be prepared to set your own <literal>astetcdir</literal>
+
path.
+
+
See
+
<link xlink:href="http://www.asterisk.org/community/documentation"/>
+
for more examples of what is possible here.
+
'';
+
};
+
+
extraArguments = mkOption {
+
default = [];
+
type = types.listOf types.str;
+
example =
+
[ "-vvvddd" "-e" "1024" ];
+
description = ''
+
Additional command line arguments to pass to Asterisk.
+
'';
+
};
+
};
+
};
+
+
config = mkIf cfg.enable {
+
users.extraUsers = singleton
+
{ name = asteriskUser;
+
uid = config.ids.uids.asterisk;
+
description = "Asterisk daemon user";
+
home = varlibdir;
+
};
+
+
systemd.services.asterisk = {
+
description = ''
+
Asterisk PBX server
+
'';
+
+
wantedBy = [ "multi-user.target" ];
+
+
preStart = ''
+
# Copy skeleton directory tree to /var
+
for d in '${varlibdir}' '${spooldir}' '${logdir}'; do
+
# TODO: Make exceptions for /var directories that likely should be updated
+
if [ ! -e "$d" ]; then
+
cp --recursive ${pkgs.asterisk}/"$d" "$d"
+
chown --recursive ${asteriskUser} "$d"
+
find "$d" -type d | xargs chmod 0755
+
fi
+
done
+
'';
+
+
serviceConfig = {
+
ExecStart =
+
let
+
# FIXME: This doesn't account for arguments with spaces
+
argString = concatStringsSep " " cfg.extraArguments;
+
in
+
"${pkgs.asterisk}/bin/asterisk -U ${asteriskUser} -C ${asteriskEtc}/asterisk.conf ${argString} -F";
+
Type = "forking";
+
PIDFile = "/var/run/asterisk/asterisk.pid";
+
};
+
};
+
};
+
}