2014-04-14 16:26:48 +02:00
|
|
|
{ config, lib, pkgs, ... }:
|
2011-12-05 02:51:05 +01:00
|
|
|
|
2014-04-14 16:26:48 +02:00
|
|
|
with lib;
|
2011-12-05 02:51:05 +01:00
|
|
|
|
|
|
|
let
|
|
|
|
|
2017-02-16 01:17:44 +01:00
|
|
|
name = "mpd";
|
|
|
|
|
2011-12-05 02:51:05 +01:00
|
|
|
uid = config.ids.uids.mpd;
|
|
|
|
gid = config.ids.gids.mpd;
|
2013-01-27 20:21:04 +01:00
|
|
|
cfg = config.services.mpd;
|
2011-12-05 02:51:05 +01:00
|
|
|
|
2013-01-27 20:21:04 +01:00
|
|
|
mpdConf = pkgs.writeText "mpd.conf" ''
|
2020-09-10 15:51:28 +02:00
|
|
|
# This file was automatically generated by NixOS. Edit mpd's configuration
|
|
|
|
# via NixOS' configuration.nix, as this file will be rewritten upon mpd's
|
|
|
|
# restart.
|
|
|
|
|
2013-01-27 20:21:04 +01:00
|
|
|
music_directory "${cfg.musicDirectory}"
|
2017-08-20 22:34:34 +02:00
|
|
|
playlist_directory "${cfg.playlistDirectory}"
|
2018-06-01 13:37:43 +02:00
|
|
|
${lib.optionalString (cfg.dbFile != null) ''
|
|
|
|
db_file "${cfg.dbFile}"
|
|
|
|
''}
|
2013-01-27 20:21:04 +01:00
|
|
|
state_file "${cfg.dataDir}/state"
|
|
|
|
sticker_file "${cfg.dataDir}/sticker.sql"
|
2015-03-14 13:08:22 +01:00
|
|
|
|
2015-12-24 00:04:04 +01:00
|
|
|
${optionalString (cfg.network.listenAddress != "any") ''bind_to_address "${cfg.network.listenAddress}"''}
|
2015-03-14 13:08:22 +01:00
|
|
|
${optionalString (cfg.network.port != 6600) ''port "${toString cfg.network.port}"''}
|
2020-05-08 16:38:16 +02:00
|
|
|
${optionalString (cfg.fluidsynth) ''
|
|
|
|
decoder {
|
|
|
|
plugin "fluidsynth"
|
|
|
|
soundfont "${pkgs.soundfont-fluid}/share/soundfonts/FluidR3_GM2-2.sf2"
|
|
|
|
}
|
|
|
|
''}
|
2015-03-14 13:08:22 +01:00
|
|
|
|
2013-01-27 20:21:04 +01:00
|
|
|
${cfg.extraConfig}
|
2014-09-15 00:06:57 +02:00
|
|
|
'';
|
2011-12-05 02:51:05 +01:00
|
|
|
|
2013-01-27 20:21:04 +01:00
|
|
|
in {
|
2011-12-05 02:51:05 +01:00
|
|
|
|
|
|
|
###### interface
|
|
|
|
|
2014-09-15 00:06:57 +02:00
|
|
|
options = {
|
2011-12-05 02:51:05 +01:00
|
|
|
|
2014-09-15 00:06:57 +02:00
|
|
|
services.mpd = {
|
2011-12-05 02:51:05 +01:00
|
|
|
|
|
|
|
enable = mkOption {
|
2016-09-09 02:45:53 +02:00
|
|
|
type = types.bool;
|
2011-12-05 02:51:05 +01:00
|
|
|
default = false;
|
|
|
|
description = ''
|
2013-01-27 20:21:04 +01:00
|
|
|
Whether to enable MPD, the music player daemon.
|
2014-09-15 00:06:57 +02:00
|
|
|
'';
|
|
|
|
};
|
2013-01-27 20:21:04 +01:00
|
|
|
|
2017-06-30 23:51:42 +02:00
|
|
|
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.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2013-01-27 20:21:04 +01:00
|
|
|
musicDirectory = mkOption {
|
2018-07-21 23:19:34 +02:00
|
|
|
type = with types; either path (strMatching "(http|https|nfs|smb)://.+");
|
2013-01-27 20:21:04 +01:00
|
|
|
default = "${cfg.dataDir}/music";
|
2017-08-20 22:34:34 +02:00
|
|
|
defaultText = ''''${dataDir}/music'';
|
2013-01-27 20:21:04 +01:00
|
|
|
description = ''
|
2018-07-21 23:19:34 +02:00
|
|
|
The directory or NFS/SMB network share where mpd reads music from.
|
2014-09-15 00:06:57 +02:00
|
|
|
'';
|
|
|
|
};
|
2013-01-27 20:21:04 +01:00
|
|
|
|
2017-08-20 22:34:34 +02:00
|
|
|
playlistDirectory = mkOption {
|
|
|
|
type = types.path;
|
|
|
|
default = "${cfg.dataDir}/playlists";
|
|
|
|
defaultText = ''''${dataDir}/playlists'';
|
|
|
|
description = ''
|
|
|
|
The directory where mpd stores playlists.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2013-01-27 20:21:04 +01:00
|
|
|
extraConfig = mkOption {
|
2016-10-23 19:33:41 +02:00
|
|
|
type = types.lines;
|
2014-09-15 00:06:57 +02:00
|
|
|
default = "";
|
2013-01-27 20:21:04 +01:00
|
|
|
description = ''
|
|
|
|
Extra directives added to to the end of MPD's configuration file,
|
|
|
|
mpd.conf. Basic configuration like file location and uid/gid
|
2017-02-16 01:17:44 +01:00
|
|
|
is added automatically to the beginning of the file. For available
|
|
|
|
options see <literal>man 5 mpd.conf</literal>'.
|
2014-09-15 00:06:57 +02:00
|
|
|
'';
|
|
|
|
};
|
2011-12-05 02:51:05 +01:00
|
|
|
|
|
|
|
dataDir = mkOption {
|
2016-09-09 02:45:53 +02:00
|
|
|
type = types.path;
|
2017-02-16 01:17:44 +01:00
|
|
|
default = "/var/lib/${name}";
|
2011-12-05 02:51:05 +01:00
|
|
|
description = ''
|
2013-01-27 20:21:04 +01:00
|
|
|
The directory where MPD stores its state, tag cache,
|
|
|
|
playlists etc.
|
2014-09-15 00:06:57 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2015-03-08 11:12:20 +01:00
|
|
|
user = mkOption {
|
2016-09-09 02:45:53 +02:00
|
|
|
type = types.str;
|
2017-02-16 01:17:44 +01:00
|
|
|
default = name;
|
2015-03-08 11:12:20 +01:00
|
|
|
description = "User account under which MPD runs.";
|
|
|
|
};
|
|
|
|
|
|
|
|
group = mkOption {
|
2016-09-09 02:45:53 +02:00
|
|
|
type = types.str;
|
2017-02-16 01:17:44 +01:00
|
|
|
default = name;
|
2015-03-08 11:12:20 +01:00
|
|
|
description = "Group account under which MPD runs.";
|
|
|
|
};
|
|
|
|
|
2014-09-15 00:06:57 +02:00
|
|
|
network = {
|
|
|
|
|
2015-12-24 00:04:04 +01:00
|
|
|
listenAddress = mkOption {
|
2016-09-09 02:45:53 +02:00
|
|
|
type = types.str;
|
2017-01-01 13:46:39 +01:00
|
|
|
default = "127.0.0.1";
|
|
|
|
example = "any";
|
2014-09-15 00:06:57 +02:00
|
|
|
description = ''
|
2017-01-01 13:46:39 +01:00
|
|
|
The address for the daemon to listen on.
|
|
|
|
Use <literal>any</literal> to listen on all addresses.
|
2014-09-15 00:06:57 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
port = mkOption {
|
2016-09-09 02:45:53 +02:00
|
|
|
type = types.int;
|
2014-09-15 00:06:57 +02:00
|
|
|
default = 6600;
|
|
|
|
description = ''
|
|
|
|
This setting is the TCP port that is desired for the daemon to get assigned
|
|
|
|
to.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
2015-04-10 23:10:14 +02:00
|
|
|
|
|
|
|
dbFile = mkOption {
|
2018-06-01 13:37:43 +02:00
|
|
|
type = types.nullOr types.str;
|
2015-04-10 23:10:14 +02:00
|
|
|
default = "${cfg.dataDir}/tag_cache";
|
2017-08-20 22:34:34 +02:00
|
|
|
defaultText = ''''${dataDir}/tag_cache'';
|
2015-04-10 23:10:14 +02:00
|
|
|
description = ''
|
2018-06-01 13:37:43 +02:00
|
|
|
The path to MPD's database. If set to <literal>null</literal> the
|
2018-06-03 09:55:26 +02:00
|
|
|
parameter is omitted from the configuration.
|
2015-04-10 23:10:14 +02:00
|
|
|
'';
|
|
|
|
};
|
2020-05-08 16:38:16 +02:00
|
|
|
|
2020-08-16 16:56:49 +02:00
|
|
|
credentialsFile = mkOption {
|
|
|
|
type = types.path;
|
|
|
|
description = ''
|
|
|
|
Path to a file to be merged with the settings during the service startup.
|
|
|
|
Useful to merge a file which is better kept out of the Nix store
|
|
|
|
because it contains sensible data like MPD's password. Example may look like this:
|
|
|
|
<literal>password "myMpdPassword@read,add,control,admin"</literal>
|
|
|
|
'';
|
|
|
|
default = "/dev/null";
|
|
|
|
example = "/var/lib/secrets/mpd.conf";
|
|
|
|
};
|
|
|
|
|
2020-05-08 16:38:16 +02:00
|
|
|
fluidsynth = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
If set, add fluidsynth soundfont and configure the plugin.
|
|
|
|
'';
|
|
|
|
};
|
2014-09-15 00:06:57 +02:00
|
|
|
};
|
2011-12-05 02:51:05 +01:00
|
|
|
|
2014-09-15 00:06:57 +02:00
|
|
|
};
|
2011-12-05 02:51:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
###### implementation
|
|
|
|
|
2013-01-27 20:21:04 +01:00
|
|
|
config = mkIf cfg.enable {
|
|
|
|
|
2017-06-30 23:51:42 +02:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2019-02-24 17:19:05 +01:00
|
|
|
systemd.tmpfiles.rules = [
|
|
|
|
"d '${cfg.dataDir}' - ${cfg.user} ${cfg.group} - -"
|
|
|
|
"d '${cfg.playlistDirectory}' - ${cfg.user} ${cfg.group} - -"
|
|
|
|
];
|
|
|
|
|
2013-01-27 20:21:04 +01:00
|
|
|
systemd.services.mpd = {
|
|
|
|
after = [ "network.target" "sound.target" ];
|
|
|
|
description = "Music Player Daemon";
|
2017-06-30 23:51:42 +02:00
|
|
|
wantedBy = optional (!cfg.startWhenNeeded) "multi-user.target";
|
2016-09-09 02:49:09 +02:00
|
|
|
|
2014-12-22 12:20:19 +01:00
|
|
|
serviceConfig = {
|
2015-06-13 23:24:19 +02:00
|
|
|
User = "${cfg.user}";
|
2020-08-16 16:56:49 +02:00
|
|
|
ExecStart = "${pkgs.mpd}/bin/mpd --no-daemon /etc/mpd.conf";
|
|
|
|
ExecStartPre = pkgs.writeScript "mpd-start-pre" ''
|
|
|
|
#!${pkgs.runtimeShell}
|
|
|
|
set -euo pipefail
|
|
|
|
cat ${mpdConf} ${cfg.credentialsFile} > /etc/mpd.conf
|
|
|
|
'';
|
2017-06-30 23:51:42 +02:00
|
|
|
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;
|
2019-10-22 16:30:14 +02:00
|
|
|
Restart = "always";
|
2014-12-22 12:20:19 +01:00
|
|
|
};
|
2013-01-27 20:21:04 +01:00
|
|
|
};
|
2020-08-16 16:56:49 +02:00
|
|
|
environment.etc."mpd.conf" = {
|
|
|
|
mode = "0640";
|
|
|
|
group = cfg.group;
|
|
|
|
user = cfg.user;
|
|
|
|
# To be modified by the service' ExecStartPre
|
|
|
|
text = ''
|
|
|
|
'';
|
|
|
|
};
|
2013-01-27 20:21:04 +01:00
|
|
|
|
2019-09-14 19:51:29 +02:00
|
|
|
users.users = optionalAttrs (cfg.user == name) {
|
|
|
|
${name} = {
|
|
|
|
inherit uid;
|
|
|
|
group = cfg.group;
|
|
|
|
extraGroups = [ "audio" ];
|
|
|
|
description = "Music Player Daemon user";
|
|
|
|
home = "${cfg.dataDir}";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
users.groups = optionalAttrs (cfg.group == name) {
|
|
|
|
${name}.gid = gid;
|
|
|
|
};
|
2011-12-05 02:51:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|