1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.freeswitch;
9 pkg = cfg.package;
10 configDirectory = pkgs.runCommand "freeswitch-config-d" { } ''
11 mkdir -p $out
12 cp -rT ${cfg.configTemplate} $out
13 chmod -R +w $out
14 ${lib.concatStringsSep "\n" (
15 lib.mapAttrsToList (fileName: filePath: ''
16 mkdir -p $out/$(dirname ${fileName})
17 cp ${filePath} $out/${fileName}
18 '') cfg.configDir
19 )}
20 '';
21 configPath = if cfg.enableReload then "/etc/freeswitch" else configDirectory;
22in
23{
24 options = {
25 services.freeswitch = {
26 enable = lib.mkEnableOption "FreeSWITCH";
27 enableReload = lib.mkOption {
28 default = false;
29 type = lib.types.bool;
30 description = ''
31 Issue the `reloadxml` command to FreeSWITCH when configuration directory changes (instead of restart).
32 See [FreeSWITCH documentation](https://freeswitch.org/confluence/display/FREESWITCH/Reloading) for more info.
33 The configuration directory is exposed at {file}`/etc/freeswitch`.
34 See also `systemd.services.*.restartIfChanged`.
35 '';
36 };
37 configTemplate = lib.mkOption {
38 type = lib.types.path;
39 default = "${config.services.freeswitch.package}/share/freeswitch/conf/vanilla";
40 defaultText = lib.literalExpression ''"''${config.services.freeswitch.package}/share/freeswitch/conf/vanilla"'';
41 example = lib.literalExpression ''"''${config.services.freeswitch.package}/share/freeswitch/conf/minimal"'';
42 description = ''
43 Configuration template to use.
44 See available templates in [FreeSWITCH repository](https://github.com/signalwire/freeswitch/tree/master/conf).
45 You can also set your own configuration directory.
46 '';
47 };
48 configDir = lib.mkOption {
49 type = with lib.types; attrsOf path;
50 default = { };
51 example = lib.literalExpression ''
52 {
53 "freeswitch.xml" = ./freeswitch.xml;
54 "dialplan/default.xml" = pkgs.writeText "dialplan-default.xml" '''
55 [xml lines]
56 ''';
57 }
58 '';
59 description = ''
60 Override file in FreeSWITCH config template directory.
61 Each top-level attribute denotes a file path in the configuration directory, its value is the file path.
62 See [FreeSWITCH documentation](https://freeswitch.org/confluence/display/FREESWITCH/Default+Configuration) for more info.
63 Also check available templates in [FreeSWITCH repository](https://github.com/signalwire/freeswitch/tree/master/conf).
64 '';
65 };
66 package = lib.mkPackageOption pkgs "freeswitch" { };
67 };
68 };
69 config = lib.mkIf cfg.enable {
70 environment.etc.freeswitch = lib.mkIf cfg.enableReload {
71 source = configDirectory;
72 };
73 systemd.services.freeswitch-config-reload = lib.mkIf cfg.enableReload {
74 before = [ "freeswitch.service" ];
75 wantedBy = [ "multi-user.target" ];
76 restartTriggers = [ configDirectory ];
77 serviceConfig = {
78 ExecStart = "/run/current-system/systemd/bin/systemctl try-reload-or-restart freeswitch.service";
79 RemainAfterExit = true;
80 Type = "oneshot";
81 };
82 };
83 systemd.services.freeswitch = {
84 description = "Free and open-source application server for real-time communication";
85 after = [ "network.target" ];
86 wantedBy = [ "multi-user.target" ];
87 serviceConfig = {
88 DynamicUser = true;
89 StateDirectory = "freeswitch";
90 ExecStart = "${pkg}/bin/freeswitch -nf \\
91 -mod ${pkg}/lib/freeswitch/mod \\
92 -conf ${configPath} \\
93 -base /var/lib/freeswitch";
94 ExecReload = "${pkg}/bin/fs_cli -x reloadxml";
95 Restart = "on-failure";
96 RestartSec = "5s";
97 CPUSchedulingPolicy = "fifo";
98 };
99 };
100 environment.systemPackages = [ pkg ];
101 };
102}