nixos/squeezelite: add pulseaudio support and refresh options (#506197)
This commit is contained in:
@@ -6,53 +6,142 @@
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
optionalString
|
||||
types
|
||||
;
|
||||
|
||||
dataDir = "/var/lib/squeezelite";
|
||||
cfg = config.services.squeezelite;
|
||||
pkg = if cfg.pulseAudio then pkgs.squeezelite-pulse else pkgs.squeezelite;
|
||||
bin = "${pkg}/bin/${pkg.pname}";
|
||||
|
||||
serviceDeps = [
|
||||
"network.target"
|
||||
"sound.target"
|
||||
]
|
||||
++ lib.optionals cfg.pulseaudio.enable (
|
||||
if config.services.pulseaudio.systemWide then
|
||||
[ "pulseaudio.service" ]
|
||||
else
|
||||
[
|
||||
"pipewire.service"
|
||||
"pipewire-pulse.socket"
|
||||
]
|
||||
);
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
###### interface
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "squeezelite" "pulseAudio" ]
|
||||
[ "services" "squeezelite" "pulseaudio" "enable" ]
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "squeezelite" "extraArguments" ]
|
||||
[ "services" "squeezelite" "extraArgs" ]
|
||||
)
|
||||
];
|
||||
|
||||
options.services.squeezelite = {
|
||||
enable = mkEnableOption "Squeezelite, a software Squeezebox emulator";
|
||||
enable = lib.mkEnableOption "Squeezelite, a software Squeezebox emulator";
|
||||
|
||||
pulseAudio = mkEnableOption "pulseaudio support";
|
||||
package = lib.mkPackageOption pkgs "squeezelite" { } // {
|
||||
default = if cfg.pulseaudio.enable then pkgs.squeezelite-pulse else pkgs.squeezelite;
|
||||
defaultText = lib.literalExpression "if config.services.squeezelite.pulseaudio.enable then pkgs.squeezelite-pulse else pkgs.squeezelite";
|
||||
};
|
||||
|
||||
extraArguments = mkOption {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = "name to report to server";
|
||||
default = null;
|
||||
};
|
||||
|
||||
mutableName = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
description = "store name in file, controllable by server";
|
||||
default = cfg.name == null;
|
||||
defaultText = lib.literalExpression "config.services.squeezelite.name == null";
|
||||
};
|
||||
|
||||
pulseaudio = {
|
||||
enable = lib.mkEnableOption "pulseaudio support";
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "group for accessing to pulseaudio socket";
|
||||
default = if config.services.pulseaudio.systemWide then "pulse-access" else "pipewire";
|
||||
defaultText = lib.literalExpression ''if config.services.pulseaudio.systemWide then "pulse-access" else "pipewire"'';
|
||||
};
|
||||
};
|
||||
|
||||
extraArgs = lib.mkOption {
|
||||
default = "";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Additional command line arguments to pass to Squeezelite.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.name == null || !cfg.mutableName;
|
||||
message = "'services.squeezelite.name' and 'services.squeezelite.mutableName' are mutually exclusive";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
!cfg.pulseaudio.enable
|
||||
|| (
|
||||
(config.services.pulseaudio.enable && config.services.pulseaudio.systemWide)
|
||||
|| (
|
||||
config.services.pipewire.enable
|
||||
&& config.services.pipewire.pulse.enable
|
||||
&& config.services.pipewire.systemWide
|
||||
)
|
||||
);
|
||||
message = ''
|
||||
`services.squeezelite.pulseaudio.enable = true' requires a system-wide Pulseaudio server. Either:
|
||||
- `services.pulseaudio.enable = true' and `services.pulseaudio.systemWide = true'
|
||||
or
|
||||
- `services.pipewire.enable = true', `services.pipewire.pulse.enable = true', and `services.pipewire.systemWide = true'
|
||||
should be set.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.squeezelite = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [
|
||||
"network.target"
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
# try and start squeezelite if it isn't already, e.g. a sound card plugged in
|
||||
"sound.target"
|
||||
];
|
||||
after = serviceDeps;
|
||||
requires = serviceDeps;
|
||||
description = "Software Squeezebox emulator";
|
||||
|
||||
environment = {
|
||||
XDG_CONFIG_HOME = "%S/squeezelite/.config";
|
||||
XDG_RUNTIME_DIR = "%t/squeezelite";
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
ExecStartPre = [
|
||||
# print available interfaces
|
||||
"${lib.getExe cfg.package} -l"
|
||||
]
|
||||
++ lib.optionals (!cfg.pulseaudio.enable) [
|
||||
# print available alsa controls
|
||||
"${lib.getExe cfg.package} -L"
|
||||
];
|
||||
ExecStart = "${lib.getExe cfg.package} ${
|
||||
lib.optionalString (cfg.name != null) "-n ${cfg.name} "
|
||||
}${lib.optionalString cfg.mutableName "-N %S/squeezelite/player-name "}${cfg.extraArgs}";
|
||||
|
||||
DynamicUser = true;
|
||||
ExecStart = "${bin} -N ${dataDir}/player-name ${cfg.extraArguments}";
|
||||
StateDirectory = baseNameOf dataDir;
|
||||
SupplementaryGroups = "audio";
|
||||
RuntimeDirectory = "squeezelite";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
StateDirectory = "squeezelite";
|
||||
StateDirectoryMode = "0700";
|
||||
SupplementaryGroups = [
|
||||
"audio"
|
||||
]
|
||||
++ lib.optionals cfg.pulseaudio.enable [
|
||||
cfg.pulseaudio.group
|
||||
];
|
||||
TimeoutStopSec = "5";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user