Commit 2bb560b3 authored by Michael Alan Dorman's avatar Michael Alan Dorman Committed by pennae
Browse files

gmrender-resurrect: Add gmediarender service

This creates a systemd unit that will start and supervise the
gmediarender daemon.
parent aa01a3b1
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -68,6 +68,13 @@
          <link linkend="opt-programs.fzf.fuzzyCompletion">programs.fzf</link>.
        </para>
      </listitem>
      <listitem>
        <para>
          <link xlink:href="https://github.com/hzeller/gmrender-resurrect">gmediarender</link>,
          a simple, headless UPnP/DLNA renderer. Available as
          <link xlink:href="options.html#opt-services.gmediarender.enable">services.gmediarender</link>.
        </para>
      </listitem>
      <listitem>
        <para>
          <link xlink:href="https://github.com/StevenBlack/hosts">stevenblack-blocklist</link>,
+2 −0
Original line number Diff line number Diff line
@@ -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).
+1 −0
Original line number Diff line number Diff line
@@ -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
+116 −0
Original line number Diff line number Diff line
{ 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;
        };
      };
    };
  };
}