diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/audio')
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/alsa.nix | 134 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/icecast.nix | 130 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/liquidsoap.nix | 74 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/mopidy.nix | 108 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/mpd.nix | 202 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/slimserver.nix | 70 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/snapserver.nix | 217 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/squeezelite.nix | 50 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/audio/ympd.nix | 57 |
9 files changed, 1042 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/audio/alsa.nix b/nixpkgs/nixos/modules/services/audio/alsa.nix new file mode 100644 index 000000000000..376aad66e236 --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/alsa.nix @@ -0,0 +1,134 @@ +# ALSA sound support. +{ config, lib, pkgs, ... }: + +with lib; + +let + + inherit (pkgs) alsaUtils; + + pulseaudioEnabled = config.hardware.pulseaudio.enable; + +in + +{ + + ###### interface + + options = { + + sound = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable ALSA sound. + ''; + }; + + enableOSSEmulation = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable ALSA OSS emulation (with certain cards sound mixing may not work!). + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = '' + defaults.pcm.!card 3 + ''; + description = '' + Set addition configuration for system-wide alsa. + ''; + }; + + mediaKeys = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable volume and capture control with keyboard media keys. + + You want to leave this disabled if you run a desktop environment + like KDE, Gnome, Xfce, etc, as those handle such things themselves. + You might want to enable this if you run a minimalistic desktop + environment or work from bare linux ttys/framebuffers. + + Enabling this will turn on <option>services.actkbd</option>. + ''; + }; + + volumeStep = mkOption { + type = types.string; + default = "1"; + example = "1%"; + description = '' + The value by which to increment/decrement volume on media keys. + + See amixer(1) for allowed values. + ''; + }; + + }; + + }; + + }; + + + ###### implementation + + config = mkIf config.sound.enable { + + environment.systemPackages = [ alsaUtils ]; + + environment.etc = mkIf (!pulseaudioEnabled && config.sound.extraConfig != "") + [ + { source = pkgs.writeText "asound.conf" config.sound.extraConfig; + target = "asound.conf"; + } + ]; + + # ALSA provides a udev rule for restoring volume settings. + services.udev.packages = [ alsaUtils ]; + + boot.kernelModules = optional config.sound.enableOSSEmulation "snd_pcm_oss"; + + systemd.services."alsa-store" = + { description = "Store Sound Card State"; + wantedBy = [ "multi-user.target" ]; + unitConfig.RequiresMountsFor = "/var/lib/alsa"; + unitConfig.ConditionVirtualization = "!systemd-nspawn"; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${pkgs.coreutils}/bin/mkdir -p /var/lib/alsa"; + ExecStop = "${alsaUtils}/sbin/alsactl store --ignore"; + }; + }; + + services.actkbd = mkIf config.sound.mediaKeys.enable { + enable = true; + bindings = [ + # "Mute" media key + { keys = [ 113 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Master toggle"; } + + # "Lower Volume" media key + { keys = [ 114 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}- unmute"; } + + # "Raise Volume" media key + { keys = [ 115 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}+ unmute"; } + + # "Mic Mute" media key + { keys = [ 190 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Capture toggle"; } + ]; + }; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/audio/icecast.nix b/nixpkgs/nixos/modules/services/audio/icecast.nix new file mode 100644 index 000000000000..6a8a0f9975b3 --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/icecast.nix @@ -0,0 +1,130 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.icecast; + configFile = pkgs.writeText "icecast.xml" '' + <icecast> + <hostname>${cfg.hostname}</hostname> + + <authentication> + <admin-user>${cfg.admin.user}</admin-user> + <admin-password>${cfg.admin.password}</admin-password> + </authentication> + + <paths> + <logdir>${cfg.logDir}</logdir> + <adminroot>${pkgs.icecast}/share/icecast/admin</adminroot> + <webroot>${pkgs.icecast}/share/icecast/web</webroot> + <alias source="/" dest="/status.xsl"/> + </paths> + + <listen-socket> + <port>${toString cfg.listen.port}</port> + <bind-address>${cfg.listen.address}</bind-address> + </listen-socket> + + <security> + <chroot>0</chroot> + <changeowner> + <user>${cfg.user}</user> + <group>${cfg.group}</group> + </changeowner> + </security> + + ${cfg.extraConf} + </icecast> + ''; +in { + + ###### interface + + options = { + + services.icecast = { + + enable = mkEnableOption "Icecast server"; + + hostname = mkOption { + type = types.str; + description = "DNS name or IP address that will be used for the stream directory lookups or possibily the playlist generation if a Host header is not provided."; + default = config.networking.domain; + }; + + admin = { + user = mkOption { + type = types.str; + description = "Username used for all administration functions."; + default = "admin"; + }; + + password = mkOption { + type = types.str; + description = "Password used for all administration functions."; + }; + }; + + logDir = mkOption { + type = types.path; + description = "Base directory used for logging."; + default = "/var/log/icecast"; + }; + + listen = { + port = mkOption { + type = types.int; + description = "TCP port that will be used to accept client connections."; + default = 8000; + }; + + address = mkOption { + type = types.str; + description = "Address Icecast will listen on."; + default = "::"; + }; + }; + + user = mkOption { + type = types.str; + description = "User privileges for the server."; + default = "nobody"; + }; + + group = mkOption { + type = types.str; + description = "Group privileges for the server."; + default = "nogroup"; + }; + + extraConf = mkOption { + type = types.lines; + description = "icecast.xml content."; + default = ""; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.icecast = { + after = [ "network.target" ]; + description = "Icecast Network Audio Streaming Server"; + wantedBy = [ "multi-user.target" ]; + + preStart = "mkdir -p ${cfg.logDir} && chown ${cfg.user}:${cfg.group} ${cfg.logDir}"; + serviceConfig = { + Type = "simple"; + ExecStart = "${pkgs.icecast}/bin/icecast -c ${configFile}"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; + }; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/audio/liquidsoap.nix b/nixpkgs/nixos/modules/services/audio/liquidsoap.nix new file mode 100644 index 000000000000..66f84ef20762 --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/liquidsoap.nix @@ -0,0 +1,74 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + streams = builtins.attrNames config.services.liquidsoap.streams; + + streamService = + name: + let stream = builtins.getAttr name config.services.liquidsoap.streams; in + { inherit name; + value = { + after = [ "network-online.target" "sound.target" ]; + description = "${name} liquidsoap stream"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.wget ]; + preStart = + '' + mkdir -p /var/log/liquidsoap + chown liquidsoap -R /var/log/liquidsoap + ''; + serviceConfig = { + PermissionsStartOnly="true"; + ExecStart = "${pkgs.liquidsoap}/bin/liquidsoap ${stream}"; + User = "liquidsoap"; + }; + }; + }; +in +{ + + ##### interface + + options = { + + services.liquidsoap.streams = mkOption { + + description = + '' + Set of Liquidsoap streams to start, + one systemd service per stream. + ''; + + default = {}; + + example = { + myStream1 = literalExample "\"/etc/liquidsoap/myStream1.liq\""; + myStream2 = literalExample "./myStream2.liq"; + myStream3 = literalExample "\"out(playlist(\\\"/srv/music/\\\"))\""; + }; + + type = types.attrsOf (types.either types.path types.str); + }; + + }; + ##### implementation + + config = mkIf (builtins.length streams != 0) { + + users.users.liquidsoap = { + uid = config.ids.uids.liquidsoap; + group = "liquidsoap"; + extraGroups = [ "audio" ]; + description = "Liquidsoap streaming user"; + home = "/var/lib/liquidsoap"; + createHome = true; + }; + + users.groups.liquidsoap.gid = config.ids.gids.liquidsoap; + + systemd.services = builtins.listToAttrs ( map streamService streams ); + }; + +} diff --git a/nixpkgs/nixos/modules/services/audio/mopidy.nix b/nixpkgs/nixos/modules/services/audio/mopidy.nix new file mode 100644 index 000000000000..e2f4ec39f94c --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/mopidy.nix @@ -0,0 +1,108 @@ +{ config, lib, pkgs, ... }: + +with pkgs; +with lib; + +let + uid = config.ids.uids.mopidy; + gid = config.ids.gids.mopidy; + cfg = config.services.mopidy; + + mopidyConf = writeText "mopidy.conf" cfg.configuration; + + mopidyEnv = buildEnv { + name = "mopidy-with-extensions-${mopidy.version}"; + paths = closePropagation cfg.extensionPackages; + pathsToLink = [ "/${python.sitePackages}" ]; + buildInputs = [ makeWrapper ]; + postBuild = '' + makeWrapper ${mopidy}/bin/mopidy $out/bin/mopidy \ + --prefix PYTHONPATH : $out/${python.sitePackages} + ''; + }; +in { + + options = { + + services.mopidy = { + + enable = mkEnableOption "Mopidy, a music player daemon"; + + dataDir = mkOption { + default = "/var/lib/mopidy"; + type = types.str; + description = '' + The directory where Mopidy stores its state. + ''; + }; + + extensionPackages = mkOption { + default = []; + type = types.listOf types.package; + example = literalExample "[ pkgs.mopidy-spotify ]"; + description = '' + Mopidy extensions that should be loaded by the service. + ''; + }; + + configuration = mkOption { + default = ""; + type = types.lines; + description = '' + The configuration that Mopidy should use. + ''; + }; + + extraConfigFiles = mkOption { + default = []; + type = types.listOf types.str; + description = '' + Extra config file read by Mopidy when the service starts. + Later files in the list overrides earlier configuration. + ''; + }; + + }; + + }; + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.mopidy = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "sound.target" ]; + description = "mopidy music player daemon"; + preStart = "mkdir -p ${cfg.dataDir} && chown -R mopidy:mopidy ${cfg.dataDir}"; + serviceConfig = { + ExecStart = "${mopidyEnv}/bin/mopidy --config ${concatStringsSep ":" ([mopidyConf] ++ cfg.extraConfigFiles)}"; + User = "mopidy"; + PermissionsStartOnly = true; + }; + }; + + systemd.services.mopidy-scan = { + description = "mopidy local files scanner"; + preStart = "mkdir -p ${cfg.dataDir} && chown -R mopidy:mopidy ${cfg.dataDir}"; + serviceConfig = { + ExecStart = "${mopidyEnv}/bin/mopidy --config ${concatStringsSep ":" ([mopidyConf] ++ cfg.extraConfigFiles)} local scan"; + User = "mopidy"; + PermissionsStartOnly = true; + Type = "oneshot"; + }; + }; + + users.users.mopidy = { + inherit uid; + group = "mopidy"; + extraGroups = [ "audio" ]; + description = "Mopidy daemon user"; + home = "${cfg.dataDir}"; + }; + + users.groups.mopidy.gid = gid; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/audio/mpd.nix b/nixpkgs/nixos/modules/services/audio/mpd.nix new file mode 100644 index 000000000000..5bfe2b6a22ad --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/mpd.nix @@ -0,0 +1,202 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + name = "mpd"; + + uid = config.ids.uids.mpd; + gid = config.ids.gids.mpd; + cfg = config.services.mpd; + + mpdConf = pkgs.writeText "mpd.conf" '' + music_directory "${cfg.musicDirectory}" + playlist_directory "${cfg.playlistDirectory}" + ${lib.optionalString (cfg.dbFile != null) '' + db_file "${cfg.dbFile}" + ''} + state_file "${cfg.dataDir}/state" + sticker_file "${cfg.dataDir}/sticker.sql" + log_file "syslog" + user "${cfg.user}" + group "${cfg.group}" + + ${optionalString (cfg.network.listenAddress != "any") ''bind_to_address "${cfg.network.listenAddress}"''} + ${optionalString (cfg.network.port != 6600) ''port "${toString cfg.network.port}"''} + + ${cfg.extraConfig} + ''; + +in { + + ###### interface + + options = { + + services.mpd = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable MPD, the music player daemon. + ''; + }; + + startWhenNeeded = mkOption { + type = types.bool; + default = false; + description = '' + If set, <command>mpd</command> is socket-activated; that + is, instead of having it permanently running as a daemon, + systemd will start it on the first incoming connection. + ''; + }; + + musicDirectory = mkOption { + type = with types; either path (strMatching "(http|https|nfs|smb)://.+"); + default = "${cfg.dataDir}/music"; + defaultText = ''''${dataDir}/music''; + description = '' + The directory or NFS/SMB network share where mpd reads music from. + ''; + }; + + playlistDirectory = mkOption { + type = types.path; + default = "${cfg.dataDir}/playlists"; + defaultText = ''''${dataDir}/playlists''; + description = '' + The directory where mpd stores playlists. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra directives added to to the end of MPD's configuration file, + mpd.conf. Basic configuration like file location and uid/gid + is added automatically to the beginning of the file. For available + options see <literal>man 5 mpd.conf</literal>'. + ''; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/${name}"; + description = '' + The directory where MPD stores its state, tag cache, + playlists etc. + ''; + }; + + user = mkOption { + type = types.str; + default = name; + description = "User account under which MPD runs."; + }; + + group = mkOption { + type = types.str; + default = name; + description = "Group account under which MPD runs."; + }; + + network = { + + listenAddress = mkOption { + type = types.str; + default = "127.0.0.1"; + example = "any"; + description = '' + The address for the daemon to listen on. + Use <literal>any</literal> to listen on all addresses. + ''; + }; + + port = mkOption { + type = types.int; + default = 6600; + description = '' + This setting is the TCP port that is desired for the daemon to get assigned + to. + ''; + }; + + }; + + dbFile = mkOption { + type = types.nullOr types.str; + default = "${cfg.dataDir}/tag_cache"; + defaultText = ''''${dataDir}/tag_cache''; + description = '' + The path to MPD's database. If set to <literal>null</literal> the + parameter is omitted from the configuration. + ''; + }; + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.sockets.mpd = mkIf cfg.startWhenNeeded { + description = "Music Player Daemon Socket"; + wantedBy = [ "sockets.target" ]; + listenStreams = [ + "${optionalString (cfg.network.listenAddress != "any") "${cfg.network.listenAddress}:"}${toString cfg.network.port}" + ]; + socketConfig = { + Backlog = 5; + KeepAlive = true; + PassCredentials = true; + }; + }; + + systemd.services.mpd = { + after = [ "network.target" "sound.target" ]; + description = "Music Player Daemon"; + wantedBy = optional (!cfg.startWhenNeeded) "multi-user.target"; + + preStart = '' + mkdir -p "${cfg.dataDir}" && chown -R ${cfg.user}:${cfg.group} "${cfg.dataDir}" + mkdir -p "${cfg.playlistDirectory}" && chown -R ${cfg.user}:${cfg.group} "${cfg.playlistDirectory}" + ''; + serviceConfig = { + User = "${cfg.user}"; + PermissionsStartOnly = true; + ExecStart = "${pkgs.mpd}/bin/mpd --no-daemon ${mpdConf}"; + Type = "notify"; + LimitRTPRIO = 50; + LimitRTTIME = "infinity"; + ProtectSystem = true; + NoNewPrivileges = true; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProtectKernelModules = true; + RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX AF_NETLINK"; + RestrictNamespaces = true; + }; + }; + + users.users = optionalAttrs (cfg.user == name) (singleton { + inherit uid; + inherit name; + group = cfg.group; + extraGroups = [ "audio" ]; + description = "Music Player Daemon user"; + home = "${cfg.dataDir}"; + }); + + users.groups = optionalAttrs (cfg.group == name) (singleton { + inherit name; + gid = gid; + }); + }; + +} diff --git a/nixpkgs/nixos/modules/services/audio/slimserver.nix b/nixpkgs/nixos/modules/services/audio/slimserver.nix new file mode 100644 index 000000000000..640403d2c97d --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/slimserver.nix @@ -0,0 +1,70 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.slimserver; + +in { + options = { + + services.slimserver = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable slimserver. + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.slimserver; + defaultText = "pkgs.slimserver"; + description = "Slimserver package to use."; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/slimserver"; + description = '' + The directory where slimserver stores its state, tag cache, + playlists etc. + ''; + }; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.slimserver = { + after = [ "network.target" ]; + description = "Slim Server for Logitech Squeezebox Players"; + wantedBy = [ "multi-user.target" ]; + + preStart = "mkdir -p ${cfg.dataDir} && chown -R slimserver:slimserver ${cfg.dataDir}"; + serviceConfig = { + User = "slimserver"; + PermissionsStartOnly = true; + # Issue 40589: Disable broken image/video support (audio still works!) + ExecStart = "${cfg.package}/slimserver.pl --logdir ${cfg.dataDir}/logs --prefsdir ${cfg.dataDir}/prefs --cachedir ${cfg.dataDir}/cache --noimage --novideo"; + }; + }; + + users = { + users.slimserver = { + description = "Slimserver daemon user"; + home = cfg.dataDir; + group = "slimserver"; + }; + groups.slimserver = {}; + }; + }; + +} + diff --git a/nixpkgs/nixos/modules/services/audio/snapserver.nix b/nixpkgs/nixos/modules/services/audio/snapserver.nix new file mode 100644 index 000000000000..f709dd7fe16b --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/snapserver.nix @@ -0,0 +1,217 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + package = "snapcast"; + name = "snapserver"; + + cfg = config.services.snapserver; + + # Using types.nullOr to inherit upstream defaults. + sampleFormat = mkOption { + type = with types; nullOr str; + default = null; + description = '' + Default sample format. + ''; + example = "48000:16:2"; + }; + + codec = mkOption { + type = with types; nullOr str; + default = null; + description = '' + Default audio compression method. + ''; + example = "flac"; + }; + + streamToOption = name: opt: + let + os = val: + optionalString (val != null) "${val}"; + os' = prefixx: val: + optionalString (val != null) (prefixx + "${val}"); + flatten = key: value: + "&${key}=${value}"; + in + "-s ${opt.type}://" + os opt.location + "?" + os' "name=" name + + concatStrings (mapAttrsToList flatten opt.query); + + optionalNull = val: ret: + optional (val != null) ret; + + optionString = concatStringsSep " " (mapAttrsToList streamToOption cfg.streams + ++ ["-p ${toString cfg.port}"] + ++ ["--controlPort ${toString cfg.controlPort}"] + ++ optionalNull cfg.sampleFormat "--sampleFormat ${cfg.sampleFormat}" + ++ optionalNull cfg.codec "-c ${cfg.codec}" + ++ optionalNull cfg.streamBuffer "--streamBuffer ${cfg.streamBuffer}" + ++ optionalNull cfg.buffer "-b ${cfg.buffer}" + ++ optional cfg.sendToMuted "--sendToMuted"); + +in { + + ###### interface + + options = { + + services.snapserver = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable snapserver. + ''; + }; + + port = mkOption { + type = types.port; + default = 1704; + description = '' + The port that snapclients can connect to. + ''; + }; + + controlPort = mkOption { + type = types.port; + default = 1705; + description = '' + The port for control connections (JSON-RPC). + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = '' + Whether to automatically open the specified ports in the firewall. + ''; + }; + + inherit sampleFormat; + inherit codec; + + streams = mkOption { + type = with types; attrsOf (submodule { + options = { + location = mkOption { + type = types.path; + description = '' + The location of the pipe. + ''; + }; + type = mkOption { + type = types.enum [ "pipe" "file" "process" "spotify" "airplay" ]; + default = "pipe"; + description = '' + The type of input stream. + ''; + }; + query = mkOption { + type = attrsOf str; + default = {}; + description = '' + Key-value pairs that convey additional parameters about a stream. + ''; + example = literalExample '' + # for type == "pipe": + { + mode = "listen"; + }; + # for type == "process": + { + params = "--param1 --param2"; + logStderr = "true"; + }; + ''; + }; + inherit sampleFormat; + inherit codec; + }; + }); + default = { default = {}; }; + description = '' + The definition for an input source. + ''; + example = literalExample '' + { + mpd = { + type = "pipe"; + location = "/run/snapserver/mpd"; + sampleFormat = "48000:16:2"; + codec = "pcm"; + }; + }; + ''; + }; + + streamBuffer = mkOption { + type = with types; nullOr int; + default = null; + description = '' + Stream read (input) buffer in ms. + ''; + example = 20; + }; + + buffer = mkOption { + type = with types; nullOr int; + default = null; + description = '' + Network buffer in ms. + ''; + example = 1000; + }; + + sendToMuted = mkOption { + type = types.bool; + default = false; + description = '' + Send audio to muted clients. + ''; + }; + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.snapserver = { + after = [ "network.target" ]; + description = "Snapserver"; + wantedBy = [ "multi-user.target" ]; + before = [ "mpd.service" "mopidy.service" ]; + + serviceConfig = { + DynamicUser = true; + ExecStart = "${pkgs.snapcast}/bin/snapserver --daemon ${optionString}"; + Type = "forking"; + LimitRTPRIO = 50; + LimitRTTIME = "infinity"; + NoNewPrivileges = true; + PIDFile = "/run/${name}/pid"; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProtectKernelModules = true; + RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX"; + RestrictNamespaces = true; + RuntimeDirectory = name; + StateDirectory = name; + }; + }; + + networking.firewall.allowedTCPPorts = optionals cfg.openFirewall [ cfg.port cfg.controlPort ]; + }; + + meta = { + maintainers = with maintainers; [ tobim ]; + }; + +} diff --git a/nixpkgs/nixos/modules/services/audio/squeezelite.nix b/nixpkgs/nixos/modules/services/audio/squeezelite.nix new file mode 100644 index 000000000000..05506f5bcc7a --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/squeezelite.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + dataDir = "/var/lib/squeezelite"; + cfg = config.services.squeezelite; + +in { + + ###### interface + + options = { + + services.squeezelite= { + + enable = mkEnableOption "Squeezelite, a software Squeezebox emulator"; + + extraArguments = mkOption { + default = ""; + type = types.str; + description = '' + Additional command line arguments to pass to Squeezelite. + ''; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.squeezelite= { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "sound.target" ]; + description = "Software Squeezebox emulator"; + serviceConfig = { + DynamicUser = true; + ExecStart = "${pkgs.squeezelite}/bin/squeezelite -N ${dataDir}/player-name ${cfg.extraArguments}"; + StateDirectory = builtins.baseNameOf dataDir; + SupplementaryGroups = "audio"; + }; + }; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/audio/ympd.nix b/nixpkgs/nixos/modules/services/audio/ympd.nix new file mode 100644 index 000000000000..919b76622510 --- /dev/null +++ b/nixpkgs/nixos/modules/services/audio/ympd.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.ympd; +in { + + ###### interface + + options = { + + services.ympd = { + + enable = mkEnableOption "ympd, the MPD Web GUI"; + + webPort = mkOption { + type = types.either types.str types.port; # string for backwards compat + default = "8080"; + description = "The port where ympd's web interface will be available."; + example = "ssl://8080:/path/to/ssl-private-key.pem"; + }; + + mpd = { + host = mkOption { + type = types.string; + default = "localhost"; + description = "The host where MPD is listening."; + example = "localhost"; + }; + + port = mkOption { + type = types.int; + default = config.services.mpd.network.port; + description = "The port where MPD is listening."; + example = 6600; + }; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.ympd = { + description = "Standalone MPD Web GUI written in C"; + wantedBy = [ "multi-user.target" ]; + serviceConfig.ExecStart = "${pkgs.ympd}/bin/ympd --host ${cfg.mpd.host} --port ${toString cfg.mpd.port} --webport ${toString cfg.webPort} --user nobody"; + }; + + }; + +} |