nixpkgs/nixos/modules/services/audio/snapserver.nix
Martin Weinelt af89f21de9
nixos/snapserver: fix default http port
This was missed in the prior review and overlaps with the TCP port.
2025-09-18 16:02:39 +02:00

258 lines
7 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
name = "snapserver";
inherit (lib)
literalExpression
mkEnableOption
mkOption
mkPackageOption
mkRemovedOptionModule
mkRenamedOptionModule
types
;
cfg = config.services.snapserver;
format = pkgs.formats.ini {
listsAsDuplicateKeys = true;
};
configFile = format.generate "snapserver.conf" cfg.settings;
in
{
imports = [
(mkRenamedOptionModule
[ "services" "snapserver" "controlPort" ]
[ "services" "snapserver" "tcp" "port" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "listenAddress" ]
[ "services" "snapserver" "settings" "stream" "bind_to_address" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "port" ]
[ "services" "snapserver" "settings" "stream" "port" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "sampleFormat" ]
[ "services" "snapserver" "settings" "stream" "sampleformat" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "codec" ]
[ "services" "snapserver" "settings" "stream" "codec" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "streamBuffer" ]
[ "services" "snapserver" "settings" "stream" "chunk_ms" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "buffer" ]
[ "services" "snapserver" "settings" "stream" "buffer" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "send" ]
[ "services" "snapserver" "settings" "stream" "chunk_ms" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "tcp" "enable" ]
[ "services" "snapserver" "settings" "tcp" "enabled" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "tcp" "listenAddress" ]
[ "services" "snapserver" "settings" "tcp" "bind_to_address" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "tcp" "port" ]
[ "services" "snapserver" "settings" "tcp" "port" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "http" "enable" ]
[ "services" "snapserver" "settings" "http" "enabled" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "http" "listenAddress" ]
[ "services" "snapserver" "settings" "http" "bind_to_address" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "http" "port" ]
[ "services" "snapserver" "settings" "http" "port" ]
)
(mkRenamedOptionModule
[ "services" "snapserver" "http" "docRoot" ]
[ "services" "snapserver" "settings" "http" "doc_root" ]
)
(mkRemovedOptionModule [
"services"
"snapserver"
"streams"
] "Configure `services.snapserver.settings.stream.source` instead")
];
###### interface
options = {
services.snapserver = {
enable = mkEnableOption "snapserver";
package = mkPackageOption pkgs "snapcast" { };
settings = mkOption {
default = { };
description = ''
Snapserver configuration.
Refer to the [example configuration](https://github.com/badaix/snapcast/blob/develop/server/etc/snapserver.conf) for possible options.
'';
type = types.submodule {
freeformType = format.type;
options = {
stream = {
bind_to_address = mkOption {
default = "::";
description = ''
Address to listen on for snapclient connections.
'';
};
port = mkOption {
type = types.port;
default = 1704;
description = ''
Port to listen on for snapclient connections.
'';
};
source = mkOption {
type = with types; either str (listOf str);
example = "pipe:///tmp/snapfifo?name=default";
description = ''
One or multiple URIs to PCM inpuit streams.
'';
};
};
tcp = {
enabled = mkEnableOption "the TCP JSON-RPC";
bind_to_address = mkOption {
default = "::";
description = ''
Address to listen on for snapclient connections.
'';
};
port = mkOption {
type = types.port;
default = 1705;
description = ''
Port to listen on for snapclient connections.
'';
};
};
http = {
enabled = mkEnableOption "the HTTP JSON-RPC";
bind_to_address = mkOption {
default = "::";
description = ''
Address to listen on for snapclient connections.
'';
};
port = mkOption {
type = types.port;
default = 1780;
description = ''
Port to listen on for snapclient connections.
'';
};
doc_root = lib.mkOption {
type = with lib.types; nullOr path;
default = pkgs.snapweb;
defaultText = literalExpression "pkgs.snapweb";
description = ''
Path to serve from the HTTP servers root.
'';
};
};
};
};
};
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to automatically open the specified ports in the firewall.
'';
};
};
};
###### implementation
config = lib.mkIf cfg.enable {
environment.etc."snapserver.conf".source = configFile;
systemd.services.snapserver = {
after = [
"network.target"
"nss-lookup.target"
];
description = "Snapserver";
wantedBy = [ "multi-user.target" ];
before = [
"mpd.service"
"mopidy.service"
];
restartTriggers = [ configFile ];
serviceConfig = {
DynamicUser = true;
ExecStart = toString [
(lib.getExe' cfg.package "snapserver")
"--daemon"
];
Type = "forking";
LimitRTPRIO = 50;
LimitRTTIME = "infinity";
NoNewPrivileges = true;
PIDFile = "/run/${name}/pid";
ProtectKernelTunables = true;
ProtectControlGroups = true;
ProtectKernelModules = true;
Restart = "on-failure";
RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX AF_NETLINK";
RestrictNamespaces = true;
RuntimeDirectory = name;
StateDirectory = name;
};
};
networking.firewall.allowedTCPPorts =
lib.optionals cfg.openFirewall [ cfg.settings.stream.port ]
++ lib.optional (cfg.openFirewall && cfg.settings.tcp.enabled) cfg.settings.tcp.port
++ lib.optional (cfg.openFirewall && cfg.settings.http.enabled) cfg.settings.http.port;
};
meta = {
maintainers = with lib.maintainers; [ tobim ];
};
}