nixos/mpd: support passwords in separate files

This allows to use files containing only the mpd password without the
permissions, making it easier for other programs connecting to mpd to read the
password from the same password file.
This commit is contained in:
sohalt 2020-12-24 00:04:10 +01:00
parent 9e6737710c
commit f7384470de

View File

@ -10,6 +10,14 @@ let
gid = config.ids.gids.mpd;
cfg = config.services.mpd;
credentialsPlaceholder = (creds:
let
placeholders = (imap0
(i: c: ''password "{{password-${toString i}}}@${concatStringsSep "," c.permissions}"'')
creds);
in
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
@ -32,6 +40,8 @@ let
}
''}
${credentialsPlaceholder cfg.credentials}
${cfg.extraConfig}
'';
@ -152,6 +162,37 @@ in {
'';
};
credentials = mkOption {
type = types.listOf (types.submodule {
options = {
passwordFile = mkOption {
type = types.path;
description = ''
Path to file containing the password.
'';
};
permissions = let
perms = ["read" "add" "control" "admin"];
in mkOption {
type = types.listOf (types.enum perms);
default = [ "read" ];
description = ''
List of permissions that are granted with this password.
Permissions can be "${concatStringsSep "\", \"" perms}".
'';
};
};
});
description = ''
Credentials and permissions for accessing the mpd server.
'';
default = [];
example = [
{passwordFile = "/var/lib/secrets/mpd_readonly_password"; permissions = [ "read" ];}
{passwordFile = "/var/lib/secrets/mpd_admin_password"; permissions = ["read" "add" "control" "admin"];}
];
};
credentialsFile = mkOption {
type = types.path;
description = ''
@ -201,12 +242,16 @@ in {
serviceConfig = mkMerge [
{
User = "${cfg.user}";
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
ExecStart = "${pkgs.mpd}/bin/mpd --no-daemon /run/mpd/mpd.conf";
ExecStartPre = pkgs.writeShellScript "mpd-start-pre" ''
set -xeuo pipefail
umask 077
cat ${mpdConf} ${cfg.credentialsFile} > /run/mpd/mpd.conf
${pkgs.replace}/bin/replace-literal -fe ${
concatStringsSep " -a " (imap0 (i: c: "\"{{password-${toString i}}}\" \"$(cat ${c.passwordFile})\"") cfg.credentials)
} /run/mpd/mpd.conf
'';
RuntimeDirectory = "mpd";
Type = "notify";
LimitRTPRIO = 50;
LimitRTTIME = "infinity";
@ -230,14 +275,6 @@ in {
})
];
};
environment.etc."mpd.conf" = {
mode = "0640";
group = cfg.group;
user = cfg.user;
# To be modified by the service' ExecStartPre
text = ''
'';
};
users.users = optionalAttrs (cfg.user == name) {
${name} = {