about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/services/audio/gmediarender.nix
blob: 2f23232d19cf23199dbe6d01b27175c881879273 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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;
        };
      };
    };
  };
}