at 18.09-beta 5.6 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 name = "mpd"; 8 9 uid = config.ids.uids.mpd; 10 gid = config.ids.gids.mpd; 11 cfg = config.services.mpd; 12 13 mpdConf = pkgs.writeText "mpd.conf" '' 14 music_directory "${cfg.musicDirectory}" 15 playlist_directory "${cfg.playlistDirectory}" 16 ${lib.optionalString (cfg.dbFile != null) '' 17 db_file "${cfg.dbFile}" 18 ''} 19 state_file "${cfg.dataDir}/state" 20 sticker_file "${cfg.dataDir}/sticker.sql" 21 log_file "syslog" 22 user "${cfg.user}" 23 group "${cfg.group}" 24 25 ${optionalString (cfg.network.listenAddress != "any") ''bind_to_address "${cfg.network.listenAddress}"''} 26 ${optionalString (cfg.network.port != 6600) ''port "${toString cfg.network.port}"''} 27 28 ${cfg.extraConfig} 29 ''; 30 31in { 32 33 ###### interface 34 35 options = { 36 37 services.mpd = { 38 39 enable = mkOption { 40 type = types.bool; 41 default = false; 42 description = '' 43 Whether to enable MPD, the music player daemon. 44 ''; 45 }; 46 47 startWhenNeeded = mkOption { 48 type = types.bool; 49 default = false; 50 description = '' 51 If set, <command>mpd</command> is socket-activated; that 52 is, instead of having it permanently running as a daemon, 53 systemd will start it on the first incoming connection. 54 ''; 55 }; 56 57 musicDirectory = mkOption { 58 type = with types; either path (strMatching "(http|https|nfs|smb)://.+"); 59 default = "${cfg.dataDir}/music"; 60 defaultText = ''''${dataDir}/music''; 61 description = '' 62 The directory or NFS/SMB network share where mpd reads music from. 63 ''; 64 }; 65 66 playlistDirectory = mkOption { 67 type = types.path; 68 default = "${cfg.dataDir}/playlists"; 69 defaultText = ''''${dataDir}/playlists''; 70 description = '' 71 The directory where mpd stores playlists. 72 ''; 73 }; 74 75 extraConfig = mkOption { 76 type = types.lines; 77 default = ""; 78 description = '' 79 Extra directives added to to the end of MPD's configuration file, 80 mpd.conf. Basic configuration like file location and uid/gid 81 is added automatically to the beginning of the file. For available 82 options see <literal>man 5 mpd.conf</literal>'. 83 ''; 84 }; 85 86 dataDir = mkOption { 87 type = types.path; 88 default = "/var/lib/${name}"; 89 description = '' 90 The directory where MPD stores its state, tag cache, 91 playlists etc. 92 ''; 93 }; 94 95 user = mkOption { 96 type = types.str; 97 default = name; 98 description = "User account under which MPD runs."; 99 }; 100 101 group = mkOption { 102 type = types.str; 103 default = name; 104 description = "Group account under which MPD runs."; 105 }; 106 107 network = { 108 109 listenAddress = mkOption { 110 type = types.str; 111 default = "127.0.0.1"; 112 example = "any"; 113 description = '' 114 The address for the daemon to listen on. 115 Use <literal>any</literal> to listen on all addresses. 116 ''; 117 }; 118 119 port = mkOption { 120 type = types.int; 121 default = 6600; 122 description = '' 123 This setting is the TCP port that is desired for the daemon to get assigned 124 to. 125 ''; 126 }; 127 128 }; 129 130 dbFile = mkOption { 131 type = types.nullOr types.str; 132 default = "${cfg.dataDir}/tag_cache"; 133 defaultText = ''''${dataDir}/tag_cache''; 134 description = '' 135 The path to MPD's database. If set to <literal>null</literal> the 136 parameter is omitted from the configuration. 137 ''; 138 }; 139 }; 140 141 }; 142 143 144 ###### implementation 145 146 config = mkIf cfg.enable { 147 148 systemd.sockets.mpd = mkIf cfg.startWhenNeeded { 149 description = "Music Player Daemon Socket"; 150 wantedBy = [ "sockets.target" ]; 151 listenStreams = [ 152 "${optionalString (cfg.network.listenAddress != "any") "${cfg.network.listenAddress}:"}${toString cfg.network.port}" 153 ]; 154 socketConfig = { 155 Backlog = 5; 156 KeepAlive = true; 157 PassCredentials = true; 158 }; 159 }; 160 161 systemd.services.mpd = { 162 after = [ "network.target" "sound.target" ]; 163 description = "Music Player Daemon"; 164 wantedBy = optional (!cfg.startWhenNeeded) "multi-user.target"; 165 166 preStart = '' 167 mkdir -p "${cfg.dataDir}" && chown -R ${cfg.user}:${cfg.group} "${cfg.dataDir}" 168 mkdir -p "${cfg.playlistDirectory}" && chown -R ${cfg.user}:${cfg.group} "${cfg.playlistDirectory}" 169 ''; 170 serviceConfig = { 171 User = "${cfg.user}"; 172 PermissionsStartOnly = true; 173 ExecStart = "${pkgs.mpd}/bin/mpd --no-daemon ${mpdConf}"; 174 Type = "notify"; 175 LimitRTPRIO = 50; 176 LimitRTTIME = "infinity"; 177 ProtectSystem = true; 178 NoNewPrivileges = true; 179 ProtectKernelTunables = true; 180 ProtectControlGroups = true; 181 ProtectKernelModules = true; 182 RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX AF_NETLINK"; 183 RestrictNamespaces = true; 184 }; 185 }; 186 187 users.users = optionalAttrs (cfg.user == name) (singleton { 188 inherit uid; 189 inherit name; 190 group = cfg.group; 191 extraGroups = [ "audio" ]; 192 description = "Music Player Daemon user"; 193 home = "${cfg.dataDir}"; 194 }); 195 196 users.groups = optionalAttrs (cfg.group == name) (singleton { 197 inherit name; 198 gid = gid; 199 }); 200 }; 201 202}