Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 123 additions & 36 deletions nixos/modules/services/audio/mpd.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
}:
let

inherit (lib)
isList
isBool
isAttrs
concatStringsSep
optionalString
foldlAttrs
boolToString
literalExpression
;

name = "mpd";

uid = config.ids.uids.mpd;
Expand All @@ -17,41 +28,83 @@ let
let
placeholders = (
lib.imap0 (
i: c: ''password "{{password-${toString i}}}@${lib.concatStringsSep "," c.permissions}"''
i: c: ''password "{{password-${toString i}}}@${concatStringsSep "," c.permissions}"''
) creds
);
in
lib.concatStringsSep "\n" placeholders
concatStringsSep "\n" placeholders
);

mpdConf = pkgs.writeText "mpd.conf" ''
# 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.

music_directory "${cfg.musicDirectory}"
playlist_directory "${cfg.playlistDirectory}"
${lib.optionalString (cfg.dbFile != null) ''
db_file "${cfg.dbFile}"
''}
state_file "${cfg.dataDir}/state"
sticker_file "${cfg.dataDir}/sticker.sql"

${lib.optionalString (
cfg.network.listenAddress != "any"
) ''bind_to_address "${cfg.network.listenAddress}"''}
${lib.optionalString (cfg.network.port != 6600) ''port "${toString cfg.network.port}"''}
${lib.optionalString (cfg.fluidsynth) ''
decoder {
plugin "fluidsynth"
soundfont "${pkgs.soundfont-fluid}/share/soundfonts/FluidR3_GM2-2.sf2"
}
''}

${lib.optionalString (cfg.credentials != [ ]) (credentialsPlaceholder cfg.credentials)}

${cfg.extraConfig}
'';
mpdConf =
let
mkSetting =
with builtins;
k: v:
if isAttrs v then
''
${k} {
${foldlAttrs (
acc: name: value:
"${acc} ${mkSetting name value}"
) "" v}
}
''
else if isList v then
foldl' (acc: elem: acc + mkSetting k elem) "" v
else if isBool v then
''
${k} "${boolToString v}"
''
else
''
${k} "${toString v}"
'';
in
pkgs.writeText "mpd.conf" ''
# 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.

music_directory "${cfg.musicDirectory}"
playlist_directory "${cfg.playlistDirectory}"
${optionalString (cfg.dbFile != null) ''
db_file "${cfg.dbFile}"
''}
state_file "${cfg.dataDir}/state"
sticker_file "${cfg.dataDir}/sticker.sql"

${optionalString (
cfg.network.listenAddress != "any"
) ''bind_to_address "${cfg.network.listenAddress}"''}
${optionalString (cfg.network.port != 6600) ''port "${toString cfg.network.port}"''}
${optionalString (cfg.fluidsynth) ''
decoder {
plugin "fluidsynth"
soundfont "${pkgs.soundfont-fluid}/share/soundfonts/FluidR3_GM2-2.sf2"
}
''}

${optionalString (cfg.credentials != [ ]) (credentialsPlaceholder cfg.credentials)}

${optionalString (!isNull cfg.settings) (
foldlAttrs (
acc: name: value:
acc + mkSetting name value
) "" cfg.settings
)}

${cfg.extraConfig}
'';

baseType =
with lib.types;
oneOf [
str
bool
int
float
path
];

in
{
Expand Down Expand Up @@ -195,7 +248,7 @@ in
default = [ "read" ];
description = ''
List of permissions that are granted with this password.
Permissions can be "${lib.concatStringsSep "\", \"" perms}".
Permissions can be "${lib.concatStringsSep ''", "'' perms}".
'';
};
};
Expand Down Expand Up @@ -229,6 +282,42 @@ in
If set, add fluidsynth soundfont and configure the plugin.
'';
};

settings = lib.mkOption {
type =
with lib.types;
nullOr (
attrsOf (oneOf [
baseType
(listOf baseType)
(attrsOf baseType)
(listOf (attrsOf baseType))
])
);
default = null;
description = ''
Manages the configuration file declaratively.
'';
example = literalExpression ''
{
# Configure two outputs; Both Pipewire and PulseAudio, the latter being disabled by default
audio_output = [
{ name = "Pipewire"; type = "pipewire"; }
{ name = "PulseAudio"; type = "pulse"; enabled = false; }
];

# Configure one input. Can also be multiple inputs by using a list of attribute sets like audio_output above
input = { plugin = "curl"; proxy = "proxy.local"; };

# Configuring a database plugin
database = { plugin = "simple"; path = /var/lib/mpd/db; };

# Set a replay gain
replaygain = "album";
replaygain_preamp = 5;
}
'';
};
};

};
Expand All @@ -245,7 +334,7 @@ in
listenStreams = [
"" # Note: this is needed to override the upstream unit
(
if pkgs.lib.hasPrefix "/" cfg.network.listenAddress then
if lib.hasPrefix "/" cfg.network.listenAddress then
cfg.network.listenAddress
else
"${
Expand All @@ -267,7 +356,7 @@ in
lib.concatStringsSep "\n" (
lib.imap0 (
i: c:
''${pkgs.replace-secret}/bin/replace-secret '{{password-${toString i}}}' '${c.passwordFile}' /run/mpd/mpd.conf''
"${pkgs.replace-secret}/bin/replace-secret '{{password-${toString i}}}' '${c.passwordFile}' /run/mpd/mpd.conf"
) cfg.credentials
)
);
Expand Down Expand Up @@ -304,9 +393,7 @@ in
};
};

users.groups = lib.optionalAttrs (cfg.group == name) {
${name}.gid = gid;
};
users.groups = lib.optionalAttrs (cfg.group == name) { ${name}.gid = gid; };
};

}