diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 3a4d3f5e1247..b6b41f6a1695 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -428,6 +428,7 @@ ./services/misc/exhibitor.nix ./services/misc/felix.nix ./services/misc/folding-at-home.nix + ./services/misc/freeswitch.nix ./services/misc/fstrim.nix ./services/misc/gammu-smsd.nix ./services/misc/geoip-updater.nix diff --git a/nixos/modules/services/misc/freeswitch.nix b/nixos/modules/services/misc/freeswitch.nix new file mode 100644 index 000000000000..0de5ba428110 --- /dev/null +++ b/nixos/modules/services/misc/freeswitch.nix @@ -0,0 +1,103 @@ +{ config, lib, pkgs, ...}: +with lib; +let + cfg = config.services.freeswitch; + pkg = cfg.package; + configDirectory = pkgs.runCommand "freeswitch-config-d" { } '' + mkdir -p $out + cp -rT ${cfg.configTemplate} $out + chmod -R +w $out + ${concatStringsSep "\n" (mapAttrsToList (fileName: filePath: '' + mkdir -p $out/$(dirname ${fileName}) + cp ${filePath} $out/${fileName} + '') cfg.configDir)} + ''; + configPath = if cfg.enableReload + then "/etc/freeswitch" + else configDirectory; +in { + options = { + services.freeswitch = { + enable = mkEnableOption "FreeSWITCH"; + enableReload = mkOption { + default = false; + type = types.bool; + description = '' + Issue the reloadxml command to FreeSWITCH when configuration directory changes (instead of restart). + See FreeSWITCH documentation for more info. + The configuration directory is exposed at /etc/freeswitch. + See also systemd.services.*.restartIfChanged. + ''; + }; + configTemplate = mkOption { + type = types.path; + default = "${config.services.freeswitch.package}/share/freeswitch/conf/vanilla"; + defaultText = literalExample "\${config.services.freeswitch.package}/share/freeswitch/conf/vanilla"; + example = literalExample "\${config.services.freeswitch.package}/share/freeswitch/conf/minimal"; + description = '' + Configuration template to use. + See available templates in FreeSWITCH repository. + You can also set your own configuration directory. + ''; + }; + configDir = mkOption { + type = with types; attrsOf path; + default = { }; + example = literalExample '' + { + "freeswitch.xml" = ./freeswitch.xml; + "dialplan/default.xml" = pkgs.writeText "dialplan-default.xml" ''' + [xml lines] + '''; + } + ''; + description = '' + Override file in FreeSWITCH config template directory. + Each top-level attribute denotes a file path in the configuration directory, its value is the file path. + See FreeSWITCH documentation for more info. + Also check available templates in FreeSWITCH repository. + ''; + }; + package = mkOption { + type = types.package; + default = pkgs.freeswitch; + defaultText = literalExample "pkgs.freeswitch"; + example = literalExample "pkgs.freeswitch"; + description = '' + FreeSWITCH package. + ''; + }; + }; + }; + config = mkIf cfg.enable { + environment.etc.freeswitch = mkIf cfg.enableReload { + source = configDirectory; + }; + systemd.services.freeswitch-config-reload = mkIf cfg.enableReload { + before = [ "freeswitch.service" ]; + wantedBy = [ "multi-user.target" ]; + restartTriggers = [ configDirectory ]; + serviceConfig = { + ExecStart = "${pkgs.systemd}/bin/systemctl try-reload-or-restart freeswitch.service"; + RemainAfterExit = true; + Type = "oneshot"; + }; + }; + systemd.services.freeswitch = { + description = "Free and open-source application server for real-time communication"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + DynamicUser = true; + StateDirectory = "freeswitch"; + ExecStart = "${pkg}/bin/freeswitch -nf \\ + -mod ${pkg}/lib/freeswitch/mod \\ + -conf ${configPath} \\ + -base /var/lib/freeswitch"; + ExecReload = "${pkg}/bin/fs_cli -x reloadxml"; + Restart = "always"; + RestartSec = "5s"; + }; + }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 89426865e1ac..2f26bb782c91 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -94,6 +94,7 @@ in flannel = handleTestOn ["x86_64-linux"] ./flannel.nix {}; fluentd = handleTest ./fluentd.nix {}; fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {}; + freeswitch = handleTest ./freeswitch.nix {}; fsck = handleTest ./fsck.nix {}; gotify-server = handleTest ./gotify-server.nix {}; gitea = handleTest ./gitea.nix {}; diff --git a/nixos/tests/freeswitch.nix b/nixos/tests/freeswitch.nix new file mode 100644 index 000000000000..349d0e7bc6f0 --- /dev/null +++ b/nixos/tests/freeswitch.nix @@ -0,0 +1,29 @@ +import ./make-test-python.nix ({ pkgs, ...} : { + name = "freeswitch"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ misuzu ]; + }; + nodes = { + node0 = { config, lib, ... }: { + networking.useDHCP = false; + networking.interfaces.eth1 = { + ipv4.addresses = [ + { + address = "192.168.0.1"; + prefixLength = 24; + } + ]; + }; + services.freeswitch = { + enable = true; + enableReload = true; + configTemplate = "${config.services.freeswitch.package}/share/freeswitch/conf/minimal"; + }; + }; + }; + testScript = '' + node0.wait_for_unit("freeswitch.service") + # Wait for SIP port to be open + node0.wait_for_open_port("5060") + ''; +}) diff --git a/pkgs/servers/sip/freeswitch/default.nix b/pkgs/servers/sip/freeswitch/default.nix index aeedf8b30aee..f6791d010883 100644 --- a/pkgs/servers/sip/freeswitch/default.nix +++ b/pkgs/servers/sip/freeswitch/default.nix @@ -111,6 +111,8 @@ stdenv.mkDerivation rec { ++ lib.unique (lib.concatMap (mod: mod.inputs) enabledModules) ++ lib.optionals stdenv.isDarwin [ SystemConfiguration ]; + enableParallelBuilding = true; + NIX_CFLAGS_COMPILE = "-Wno-error"; hardeningDisable = [ "format" ]; @@ -123,6 +125,8 @@ stdenv.mkDerivation rec { postInstall = '' # helper for compiling modules... not generally useful; also pulls in perl dependency rm "$out"/bin/fsxs + # include configuration templates + cp -r conf $out/share/freeswitch/ ''; meta = {