diff --git a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml index c48907b8702..b4ff52767f6 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml @@ -68,6 +68,13 @@ programs.fzf. + + + gmediarender, + a simple, headless UPnP/DLNA renderer. Available as + services.gmediarender. + + stevenblack-blocklist, diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index 07f6d729b64..803e9eb6e43 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -26,6 +26,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [fzf](https://github.com/junegunn/fzf), a command line fuzzyfinder. Available as [programs.fzf](#opt-programs.fzf.fuzzyCompletion). +- [gmediarender](https://github.com/hzeller/gmrender-resurrect), a simple, headless UPnP/DLNA renderer. Available as [services.gmediarender](options.html#opt-services.gmediarender.enable). + - [stevenblack-blocklist](https://github.com/StevenBlack/hosts), A unified hosts file with base extensions for blocking unwanted websites. Available as [networking.stevenblack](options.html#opt-networking.stevenblack.enable). - [atuin](https://github.com/ellie/atuin), a sync server for shell history. Available as [services.atuin](#opt-services.atuin.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 0d98752e201..dce6e878540 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -295,6 +295,7 @@ ./services/amqp/rabbitmq.nix ./services/audio/alsa.nix ./services/audio/botamusique.nix + ./services/audio/gmediarender.nix ./services/audio/hqplayerd.nix ./services/audio/icecast.nix ./services/audio/jack.nix diff --git a/nixos/modules/services/audio/gmediarender.nix b/nixos/modules/services/audio/gmediarender.nix new file mode 100644 index 00000000000..2f23232d19c --- /dev/null +++ b/nixos/modules/services/audio/gmediarender.nix @@ -0,0 +1,116 @@ +{ pkgs, lib, config, utils, ... }: + +with lib; + +let + cfg = config.services.gmediarender; +in +{ + options.services.gmediarender = { + enable = mkEnableOption (mdDoc "the gmediarender DLNA renderer"); + + audioDevice = mkOption { + type = types.nullOr types.str; + default = null; + description = mdDoc '' + The audio device to use. + ''; + }; + + audioSink = mkOption { + type = types.nullOr types.str; + default = null; + description = mdDoc '' + The audio sink to use. + ''; + }; + + friendlyName = mkOption { + type = types.nullOr types.str; + default = null; + description = mdDoc '' + A "friendly name" for identifying the endpoint. + ''; + }; + + initialVolume = mkOption { + type = types.nullOr types.int; + default = 0; + description = mdDoc '' + A default volume attenuation (in dB) for the endpoint. + ''; + }; + + package = mkPackageOptionMD pkgs "gmediarender" { + default = "gmrender-resurrect"; + }; + + port = mkOption { + type = types.nullOr types.port; + default = null; + description = mdDoc "Port that will be used to accept client connections."; + }; + + uuid = mkOption { + type = types.nullOr types.str; + default = null; + description = mdDoc '' + A UUID for uniquely identifying the endpoint. If you have + multiple renderers on your network, you MUST set this. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd = { + services.gmediarender = { + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + description = "gmediarender server daemon"; + environment = { + XDG_CACHE_HOME = "%t/gmediarender"; + }; + serviceConfig = { + DynamicUser = true; + User = "gmediarender"; + Group = "gmediarender"; + SupplementaryGroups = [ "audio" ]; + ExecStart = + "${cfg.package}/bin/gmediarender " + + optionalString (cfg.audioDevice != null) ("--gstout-audiodevice=${utils.escapeSystemdExecArg cfg.audioDevice} ") + + optionalString (cfg.audioSink != null) ("--gstout-audiosink=${utils.escapeSystemdExecArg cfg.audioSink} ") + + optionalString (cfg.friendlyName != null) ("--friendly-name=${utils.escapeSystemdExecArg cfg.friendlyName} ") + + optionalString (cfg.initialVolume != 0) ("--initial-volume=${toString cfg.initialVolume} ") + + optionalString (cfg.port != null) ("--port=${toString cfg.port} ") + + optionalString (cfg.uuid != null) ("--uuid=${utils.escapeSystemdExecArg cfg.uuid} "); + Restart = "always"; + RuntimeDirectory = "gmediarender"; + + # Security options: + CapabilityBoundingSet = ""; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + # PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" "~@privileged" ]; + UMask = 066; + }; + }; + }; + }; +}