nixos/mpd: apply RFC 42 (#456989)
This commit is contained in:
@@ -12,46 +12,85 @@ let
|
||||
gid = config.ids.gids.mpd;
|
||||
cfg = config.services.mpd;
|
||||
|
||||
credentialsPlaceholder = (
|
||||
creds:
|
||||
let
|
||||
placeholders = (
|
||||
lib.imap0 (
|
||||
i: c: ''password "{{password-${toString i}}}@${lib.concatStringsSep "," c.permissions}"''
|
||||
) creds
|
||||
);
|
||||
in
|
||||
lib.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}
|
||||
'';
|
||||
mkKeyValue =
|
||||
a:
|
||||
lib.mapAttrsToList (
|
||||
k: v:
|
||||
k
|
||||
+ " "
|
||||
+ (
|
||||
if builtins.isBool v then
|
||||
# Mainly for https://mpd.readthedocs.io/en/stable/user.html#zeroconf
|
||||
"\"" + (lib.boolToYesNo v) + "\""
|
||||
else
|
||||
"\"" + (toString v) + "\""
|
||||
)
|
||||
) a;
|
||||
nonBlockSettings = lib.filterAttrs (n: v: !(builtins.isAttrs v || builtins.isList v)) cfg.settings;
|
||||
pureBlockSettings = builtins.removeAttrs cfg.settings (builtins.attrNames nonBlockSettings);
|
||||
blocks =
|
||||
pureBlockSettings
|
||||
// lib.optionalAttrs cfg.fluidsynth {
|
||||
decoder = (pureBlockSettings.decoder or [ ]) ++ [
|
||||
{
|
||||
plugin = "fluidsynth";
|
||||
soundfont = "${pkgs.soundfont-fluid}/share/soundfonts/FluidR3_GM2-2.sf2";
|
||||
}
|
||||
];
|
||||
};
|
||||
processSingleBlock =
|
||||
n: v:
|
||||
[
|
||||
(n + " {")
|
||||
]
|
||||
# Add indentation, for better readability
|
||||
++ (map (l: " " + l) (mkKeyValue v))
|
||||
++ [ "}" ];
|
||||
mpdConf = pkgs.writeTextFile {
|
||||
name = "mpd.conf";
|
||||
text = ''
|
||||
# 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.
|
||||
''
|
||||
+ lib.concatStringsSep "\n" (
|
||||
mkKeyValue (
|
||||
{
|
||||
state_file = "${cfg.dataDir}/state";
|
||||
sticker_file = "${cfg.dataDir}/sticker.sql";
|
||||
}
|
||||
// nonBlockSettings
|
||||
)
|
||||
++ lib.flatten (
|
||||
lib.mapAttrsToList (
|
||||
n: v: if builtins.isList v then (map (b: processSingleBlock n b) v) else (processSingleBlock n v)
|
||||
) blocks
|
||||
)
|
||||
++ lib.imap0 (
|
||||
i: a: "password \"{{password-${toString i}}}@${lib.concatStringsSep "," a.permissions}\""
|
||||
) cfg.credentials
|
||||
);
|
||||
derivationArgs = {
|
||||
expectScript = ''
|
||||
spawn ${lib.getExe pkgs.buildPackages.mpd} --no-daemon "$env(out)"
|
||||
expect {
|
||||
"exception: Error in \"$env(out)\"" {
|
||||
puts "Config file invalid\n"
|
||||
exit 1
|
||||
}
|
||||
"exception:" {
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
'';
|
||||
passAsFile = [
|
||||
"expectScript"
|
||||
];
|
||||
};
|
||||
checkPhase = ''
|
||||
${lib.getExe pkgs.buildPackages.expect} -f "$expectScriptPath"
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
@@ -80,39 +119,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
musicDirectory = lib.mkOption {
|
||||
type = with lib.types; either path (strMatching "(http|https|nfs|smb)://.+");
|
||||
default = "${cfg.dataDir}/music";
|
||||
defaultText = lib.literalExpression ''"''${dataDir}/music"'';
|
||||
description = ''
|
||||
The directory or NFS/SMB network share where MPD reads music from. If left
|
||||
as the default value this directory will automatically be created before
|
||||
the MPD server starts, otherwise the sysadmin is responsible for ensuring
|
||||
the directory exists with appropriate ownership and permissions.
|
||||
'';
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "User account under which MPD runs.";
|
||||
};
|
||||
|
||||
playlistDirectory = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "${cfg.dataDir}/playlists";
|
||||
defaultText = lib.literalExpression ''"''${dataDir}/playlists"'';
|
||||
description = ''
|
||||
The directory where MPD stores playlists. If left as the default value
|
||||
this directory will automatically be created before the MPD server starts,
|
||||
otherwise the sysadmin is responsible for ensuring the directory exists
|
||||
with appropriate ownership and permissions.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra directives added to to the end of MPD's configuration file,
|
||||
mpd.conf. Basic configuration like file location and uid/gid
|
||||
is added automatically to the beginning of the file. For available
|
||||
options see {manpage}`mpd.conf(5)`.
|
||||
'';
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Group account under which MPD runs.";
|
||||
};
|
||||
|
||||
dataDir = lib.mkOption {
|
||||
@@ -126,48 +142,135 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "User account under which MPD runs.";
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Open ports in the firewall for mpd.";
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Group account under which MPD runs.";
|
||||
};
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType =
|
||||
let
|
||||
inherit (lib.types)
|
||||
oneOf
|
||||
attrsOf
|
||||
listOf
|
||||
str
|
||||
int
|
||||
bool
|
||||
path
|
||||
;
|
||||
atomType = oneOf [
|
||||
str
|
||||
int
|
||||
bool
|
||||
path
|
||||
];
|
||||
in
|
||||
attrsOf (oneOf [
|
||||
atomType
|
||||
(listOf (attrsOf atomType))
|
||||
]);
|
||||
options = {
|
||||
music_directory = lib.mkOption {
|
||||
type = with lib.types; either path (strMatching "([a-z]+)://.+");
|
||||
default = "${cfg.dataDir}/music";
|
||||
defaultText = lib.literalExpression ''"''${dataDir}/music"'';
|
||||
description = ''
|
||||
The directory or URI where MPD reads music from. If left
|
||||
as the default value this directory will automatically be created before
|
||||
the MPD server starts, otherwise the sysadmin is responsible for ensuring
|
||||
the directory exists with appropriate ownership and permissions.
|
||||
'';
|
||||
};
|
||||
|
||||
network = {
|
||||
playlist_directory = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "${cfg.dataDir}/playlists";
|
||||
defaultText = lib.literalExpression ''"''${dataDir}/playlists"'';
|
||||
description = ''
|
||||
The directory where MPD stores playlists. If left as the default value
|
||||
this directory will automatically be created before the MPD server starts,
|
||||
otherwise the sysadmin is responsible for ensuring the directory exists
|
||||
with appropriate ownership and permissions.
|
||||
'';
|
||||
};
|
||||
|
||||
listenAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
example = "any";
|
||||
description = ''
|
||||
The address for the daemon to listen on.
|
||||
Use `any` to listen on all addresses.
|
||||
'';
|
||||
bind_to_address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
example = "any";
|
||||
description = ''
|
||||
The address for the daemon to listen on.
|
||||
Use `any` to listen on all addresses.
|
||||
'';
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 6600;
|
||||
description = ''
|
||||
This setting is the TCP port that is desired for the daemon to get assigned
|
||||
to.
|
||||
'';
|
||||
};
|
||||
|
||||
db_file = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "${cfg.dataDir}/tag_cache";
|
||||
defaultText = lib.literalExpression ''"''${dataDir}/tag_cache"'';
|
||||
description = ''
|
||||
The path to MPD's database.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 6600;
|
||||
description = ''
|
||||
This setting is the TCP port that is desired for the daemon to get assigned
|
||||
to.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
dbFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "${cfg.dataDir}/tag_cache";
|
||||
defaultText = lib.literalExpression ''"''${dataDir}/tag_cache"'';
|
||||
default = { };
|
||||
description = ''
|
||||
The path to MPD's database. If set to `null` the
|
||||
parameter is omitted from the configuration.
|
||||
Configuration for MPD. MPD supports key-value like blocks for settings
|
||||
like `audio_output` and `neighbor`. Some of these blocks can be
|
||||
specified multiple times, so the following configuration:
|
||||
|
||||
```txt
|
||||
audio_output {
|
||||
device "iec958:CARD=Intel,DEV=0"
|
||||
mixer_control "PCM"
|
||||
name "My specific ALSA output"
|
||||
type "alsa"
|
||||
}
|
||||
audio_output {
|
||||
mixer_type "null"
|
||||
name "ALSA Null"
|
||||
type "alsa"
|
||||
}
|
||||
audio_output {
|
||||
name "The Pulse"
|
||||
type "pulse"
|
||||
}
|
||||
```
|
||||
|
||||
Can be inserted with:
|
||||
|
||||
```nix
|
||||
audio_output = [
|
||||
{
|
||||
type = "alsa";
|
||||
name = "My specific ALSA output";
|
||||
device = "iec958:CARD=Intel,DEV=0";
|
||||
mixer_control = "PCM";
|
||||
}
|
||||
{
|
||||
type = "alsa";
|
||||
name = "ALSA Null";
|
||||
mixer_type = "null";
|
||||
}
|
||||
{
|
||||
type = "pulse";
|
||||
name = "The Pulse";
|
||||
}
|
||||
];
|
||||
```
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -226,7 +329,7 @@ in
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If set, add fluidsynth soundfont and configure the plugin.
|
||||
If set, add fluidsynth soundfont `decoder` block.
|
||||
'';
|
||||
};
|
||||
};
|
||||
@@ -235,8 +338,47 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "mpd" "musicDirectory" ]
|
||||
[ "services" "mpd" "settings" "music_directory" ]
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "mpd" "playlistDirectory" ]
|
||||
[ "services" "mpd" "settings" "playlist_directory" ]
|
||||
)
|
||||
(lib.mkRenamedOptionModule [ "services" "mpd" "dbFile" ] [ "services" "mpd" "settings" "db_file" ])
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "mpd" "network" "listenAddress" ]
|
||||
[ "services" "mpd" "settings" "bind_to_address" ]
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "mpd" "network" "port" ]
|
||||
[ "services" "mpd" "settings" "port" ]
|
||||
)
|
||||
(lib.mkRemovedOptionModule
|
||||
[
|
||||
"services"
|
||||
"mpd"
|
||||
"extraConfig"
|
||||
]
|
||||
"services.mpd.extraConfig was replaced by the declarative services.mpd.settings option, per RFC42."
|
||||
)
|
||||
];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
warnings =
|
||||
lib.optional
|
||||
(
|
||||
!(builtins.elem cfg.bind_to_address [
|
||||
"localhost"
|
||||
"127.0.0.1"
|
||||
])
|
||||
&& !cfg.openFirewall
|
||||
)
|
||||
"Using '${cfg.bind_to_address}' as services.mpd.settings.bind_to_address without enabling services.mpd.openFirewall, might prevent you from accessing MPD from other clients.";
|
||||
|
||||
# install mpd units
|
||||
systemd.packages = [ pkgs.mpd ];
|
||||
|
||||
@@ -245,12 +387,12 @@ in
|
||||
listenStreams = [
|
||||
"" # Note: this is needed to override the upstream unit
|
||||
(
|
||||
if pkgs.lib.hasPrefix "/" cfg.network.listenAddress then
|
||||
cfg.network.listenAddress
|
||||
if pkgs.lib.hasPrefix "/" cfg.settings.bind_to_address then
|
||||
cfg.settings.bind_to_address
|
||||
else
|
||||
"${
|
||||
lib.optionalString (cfg.network.listenAddress != "any") "${cfg.network.listenAddress}:"
|
||||
}${toString cfg.network.port}"
|
||||
lib.optionalString (cfg.settings.bind_to_address != "any") "${cfg.settings.bind_to_address}:"
|
||||
}${toString cfg.settings.port}"
|
||||
)
|
||||
];
|
||||
};
|
||||
@@ -282,17 +424,19 @@ in
|
||||
StateDirectory =
|
||||
[ ]
|
||||
++ lib.optionals (cfg.dataDir == "/var/lib/${name}") [ name ]
|
||||
++ lib.optionals (cfg.playlistDirectory == "/var/lib/${name}/playlists") [
|
||||
++ lib.optionals (cfg.settings.playlist_directory == "/var/lib/${name}/playlists") [
|
||||
name
|
||||
"${name}/playlists"
|
||||
]
|
||||
++ lib.optionals (cfg.musicDirectory == "/var/lib/${name}/music") [
|
||||
++ lib.optionals (cfg.settings.music_directory == "/var/lib/${name}/music") [
|
||||
name
|
||||
"${name}/music"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [ cfg.settings.port ];
|
||||
|
||||
users.users = lib.optionalAttrs (cfg.user == name) {
|
||||
${name} = {
|
||||
inherit uid;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
let
|
||||
cfg = config.services.mpdscribble;
|
||||
mpdCfg = config.services.mpd;
|
||||
mpdOpt = options.services.mpd;
|
||||
|
||||
endpointUrls = {
|
||||
"last.fm" = "http://post.audioscrobbler.com";
|
||||
@@ -114,11 +113,11 @@ in
|
||||
|
||||
host = lib.mkOption {
|
||||
default = (
|
||||
if mpdCfg.network.listenAddress != "any" then mpdCfg.network.listenAddress else "localhost"
|
||||
if mpdCfg.settings.bind_to_address != "any" then mpdCfg.settings.bind_to_address else "localhost"
|
||||
);
|
||||
defaultText = lib.literalExpression ''
|
||||
if config.${mpdOpt.network.listenAddress} != "any"
|
||||
then config.${mpdOpt.network.listenAddress}
|
||||
if config.services.mpd.settings.bind_to_address != "any"
|
||||
then config.services.mpd.settings.bind_to_address
|
||||
else "localhost"
|
||||
'';
|
||||
type = lib.types.str;
|
||||
@@ -148,8 +147,8 @@ in
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
default = mpdCfg.network.port;
|
||||
defaultText = lib.literalExpression "config.${mpdOpt.network.port}";
|
||||
default = mpdCfg.settings.port;
|
||||
defaultText = lib.literalExpression "config.services.mpd.settings.port";
|
||||
type = lib.types.port;
|
||||
description = ''
|
||||
Port for the mpdscribble daemon to search for a mpd daemon on.
|
||||
|
||||
@@ -33,8 +33,8 @@ in
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = config.services.mpd.network.port;
|
||||
defaultText = lib.literalExpression "config.services.mpd.network.port";
|
||||
default = config.services.mpd.settings.port;
|
||||
defaultText = lib.literalExpression "config.services.mpd.settings.port";
|
||||
description = "The port where MPD is listening.";
|
||||
example = 6600;
|
||||
};
|
||||
|
||||
+32
-34
@@ -1,28 +1,18 @@
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
track = pkgs.fetchurl {
|
||||
# Sourced from http://freemusicarchive.org/music/Blue_Wave_Theory/Surf_Music_Month_Challenge/Skyhawk_Beach_fade_in
|
||||
# Sourced from https://freemusicarchive.org/music/Jazz_at_Mladost_Club/Jazz_Night/Blue_bossa/
|
||||
|
||||
name = "Blue_Wave_Theory-Skyhawk_Beach.mp3";
|
||||
url = "https://freemusicarchive.org/file/music/ccCommunity/Blue_Wave_Theory/Surf_Music_Month_Challenge/Blue_Wave_Theory_-_04_-_Skyhawk_Beach.mp3";
|
||||
hash = "sha256-91VDWwrcP6Cw4rk72VHvZ8RGfRBrpRE8xo/02dcJhHc=";
|
||||
name = "Blue bossa - Jazz at Miadost Club.mp3";
|
||||
url = "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Jazz_at_Mladost_Club/Jazz_Night/Jazz_at_Mladost_Club_-_07_-_Blue_bossa.mp3?download=1&name=Jazz%20at%20Mladost%20Club%20-%20Blue%20bossa.mp3";
|
||||
hash = "sha256-cAG4nBuc97J3ZJc9cm/6vWTgnPL/Hfkar7cA3+89rto=";
|
||||
meta.license = lib.licenses.cc-by-sa-40;
|
||||
};
|
||||
|
||||
defaultCfg = rec {
|
||||
defaultMpdCfg = {
|
||||
user = "mpd";
|
||||
group = "mpd";
|
||||
dataDir = "/var/lib/mpd";
|
||||
musicDirectory = "${dataDir}/music";
|
||||
};
|
||||
|
||||
defaultMpdCfg = {
|
||||
inherit (defaultCfg)
|
||||
dataDir
|
||||
musicDirectory
|
||||
user
|
||||
group
|
||||
;
|
||||
enable = true;
|
||||
};
|
||||
|
||||
@@ -30,7 +20,7 @@ let
|
||||
{
|
||||
user,
|
||||
group,
|
||||
musicDirectory,
|
||||
dataDir,
|
||||
}:
|
||||
{
|
||||
description = "Sets up the music file(s) for MPD to use.";
|
||||
@@ -38,7 +28,7 @@ let
|
||||
after = [ "mpd.service" ];
|
||||
wantedBy = [ "default.target" ];
|
||||
script = ''
|
||||
cp ${track} ${musicDirectory}
|
||||
cp ${track} ${dataDir}/music
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = user;
|
||||
@@ -57,7 +47,10 @@ in
|
||||
{
|
||||
name = "mpd";
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ emmanuelrosa ];
|
||||
maintainers = with lib.maintainers; [
|
||||
emmanuelrosa
|
||||
doronbehar
|
||||
];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
@@ -68,18 +61,20 @@ in
|
||||
lib.mkMerge [
|
||||
(mkServer {
|
||||
mpd = defaultMpdCfg // {
|
||||
network.listenAddress = "any";
|
||||
extraConfig = ''
|
||||
audio_output {
|
||||
type "alsa"
|
||||
name "ALSA"
|
||||
mixer_type "null"
|
||||
}
|
||||
'';
|
||||
settings = {
|
||||
bind_to_address = "any";
|
||||
audio_output = [
|
||||
{
|
||||
type = "alsa";
|
||||
name = "ALSA";
|
||||
mixer_type = "null";
|
||||
}
|
||||
];
|
||||
};
|
||||
openFirewall = true;
|
||||
};
|
||||
musicService = musicService { inherit (defaultMpdCfg) user group musicDirectory; };
|
||||
musicService = musicService { inherit (defaultMpdCfg) user group dataDir; };
|
||||
})
|
||||
{ networking.firewall.allowedTCPPorts = [ 6600 ]; }
|
||||
];
|
||||
|
||||
serverPulseAudio =
|
||||
@@ -87,15 +82,15 @@ in
|
||||
lib.mkMerge [
|
||||
(mkServer {
|
||||
mpd = defaultMpdCfg // {
|
||||
extraConfig = ''
|
||||
audio_output {
|
||||
type "pulse"
|
||||
name "The Pulse"
|
||||
settings.audio_output = [
|
||||
{
|
||||
type = "pulse";
|
||||
name = "The Pulse";
|
||||
}
|
||||
'';
|
||||
];
|
||||
};
|
||||
|
||||
musicService = musicService { inherit (defaultMpdCfg) user group musicDirectory; };
|
||||
musicService = musicService { inherit (defaultMpdCfg) user group dataDir; };
|
||||
})
|
||||
{
|
||||
services.pulseaudio = {
|
||||
@@ -144,5 +139,8 @@ in
|
||||
# The PulseAudio-based server is configured not to accept external client connections
|
||||
# to perform the following test:
|
||||
client.fail(f"{mpc} -h serverPulseAudio status")
|
||||
# For inspecting these files
|
||||
serverALSA.copy_from_vm("/run/mpd/mpd.conf", "ALSA")
|
||||
serverPulseAudio.copy_from_vm("/run/mpd/mpd.conf", "PulseAudio")
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
(stdenv.hostPlatform.isDarwin && lib.versionOlder stdenv.hostPlatform.darwinSdkVersion "12.0")
|
||||
''
|
||||
substituteInPlace src/output/plugins/OSXOutputPlugin.cxx \
|
||||
--replace kAudioObjectPropertyElement{Main,Master} \
|
||||
--replace kAudioHardwareServiceDeviceProperty_Virtual{Main,Master}Volume
|
||||
--replace-fail kAudioObjectPropertyElement{Main,Master} \
|
||||
--replace-fail kAudioHardwareServiceDeviceProperty_Virtual{Main,Master}Volume
|
||||
''
|
||||
+
|
||||
lib.optionalString
|
||||
@@ -262,17 +262,19 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
];
|
||||
|
||||
mesonFlags = [
|
||||
"-Dtest=true"
|
||||
"-Dmanpages=true"
|
||||
"-Dhtml_manual=true"
|
||||
(lib.mesonBool "test" true)
|
||||
(lib.mesonBool "manpages" true)
|
||||
(lib.mesonBool "html_manual" true)
|
||||
]
|
||||
++ map (x: "-D${x}=enabled") features_
|
||||
++ map (x: "-D${x}=disabled") (lib.subtractLists features_ knownFeatures)
|
||||
++ map (x: lib.mesonEnable x true) features_
|
||||
++ map (x: lib.mesonEnable x false) (lib.subtractLists features_ knownFeatures)
|
||||
++ lib.optional (builtins.elem "zeroconf" features_) (
|
||||
"-Dzeroconf=" + (if stdenv.hostPlatform.isDarwin then "bonjour" else "avahi")
|
||||
lib.mesonOption "zeroconf" (if stdenv.hostPlatform.isDarwin then "bonjour" else "avahi")
|
||||
)
|
||||
++ lib.optional (builtins.elem "systemd" features_) "-Dsystemd_system_unit_dir=etc/systemd/system"
|
||||
++ lib.optional (builtins.elem "qobuz" features_) "-Dnlohmann_json=enabled";
|
||||
++ lib.optional (builtins.elem "systemd" features_) (
|
||||
lib.mesonOption "systemd_system_unit_dir" "etc/systemd/system"
|
||||
)
|
||||
++ lib.optional (builtins.elem "qobuz" features_) (lib.mesonEnable "nlohmann_json" true);
|
||||
|
||||
passthru.tests.nixos = nixosTests.mpd;
|
||||
|
||||
@@ -282,6 +284,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
license = lib.licenses.gpl2Only;
|
||||
maintainers = with lib.maintainers; [
|
||||
tobim
|
||||
doronbehar
|
||||
];
|
||||
platforms = lib.platforms.unix;
|
||||
mainProgram = "mpd";
|
||||
|
||||
Reference in New Issue
Block a user