mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-11 04:05:40 +03:00
nixos/lavalink: init
This commit is contained in:
parent
4aa840d154
commit
8204df50e6
2 changed files with 336 additions and 0 deletions
|
@ -408,6 +408,7 @@
|
||||||
./services/audio/icecast.nix
|
./services/audio/icecast.nix
|
||||||
./services/audio/jack.nix
|
./services/audio/jack.nix
|
||||||
./services/audio/jmusicbot.nix
|
./services/audio/jmusicbot.nix
|
||||||
|
./services/audio/lavalink.nix
|
||||||
./services/audio/liquidsoap.nix
|
./services/audio/liquidsoap.nix
|
||||||
./services/audio/marytts.nix
|
./services/audio/marytts.nix
|
||||||
./services/audio/mopidy.nix
|
./services/audio/mopidy.nix
|
||||||
|
|
335
nixos/modules/services/audio/lavalink.nix
Normal file
335
nixos/modules/services/audio/lavalink.nix
Normal file
|
@ -0,0 +1,335 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mkOption
|
||||||
|
mkEnableOption
|
||||||
|
mkIf
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
|
cfg = config.services.lavalink;
|
||||||
|
|
||||||
|
format = pkgs.formats.yaml { };
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.services.lavalink = {
|
||||||
|
enable = mkEnableOption "Lavalink";
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "lavalink" { };
|
||||||
|
|
||||||
|
password = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "s3cRe!p4SsW0rD";
|
||||||
|
description = ''
|
||||||
|
The password for Lavalink's authentication in plain text.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 2333;
|
||||||
|
example = 4567;
|
||||||
|
description = ''
|
||||||
|
The port that Lavalink will use.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
address = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
example = "127.0.0.1";
|
||||||
|
description = ''
|
||||||
|
The network address to bind to.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
Whether to expose the port to the network.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "lavalink";
|
||||||
|
example = "root";
|
||||||
|
description = ''
|
||||||
|
The user of the service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "lavalink";
|
||||||
|
example = "medias";
|
||||||
|
description = ''
|
||||||
|
The group of the service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/var/lib/lavalink";
|
||||||
|
example = "/home/lavalink";
|
||||||
|
description = ''
|
||||||
|
The home directory for lavalink.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
enableHttp2 = mkEnableOption "HTTP/2 support";
|
||||||
|
|
||||||
|
jvmArgs = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "-Xmx4G";
|
||||||
|
example = "-Djava.io.tmpdir=/var/lib/lavalink/tmp -Xmx6G";
|
||||||
|
description = ''
|
||||||
|
Set custom JVM arguments.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentFile = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "/run/secrets/lavalink/passwordEnvFile";
|
||||||
|
description = ''
|
||||||
|
Add custom environment variables from a file.
|
||||||
|
See <https://lavalink.dev/configuration/index.html#example-environment-variables> for the full documentation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = mkOption {
|
||||||
|
type = types.listOf (
|
||||||
|
types.submodule {
|
||||||
|
options = {
|
||||||
|
dependency = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "dev.lavalink.youtube:youtube-plugin:1.8.0";
|
||||||
|
description = ''
|
||||||
|
The coordinates of the plugin.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
repository = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "https://maven.example.com/releases";
|
||||||
|
default = "https://maven.lavalink.dev/releases";
|
||||||
|
description = ''
|
||||||
|
The plugin repository. Defaults to the lavalink releases repository.
|
||||||
|
|
||||||
|
To use the snapshots repository, use <https://maven.lavalink.dev/snapshots> instead
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hash = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = lib.fakeHash;
|
||||||
|
description = ''
|
||||||
|
The hash of the plugin.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
configName = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
example = "youtube";
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The name of the plugin to use as the key for the plugin configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.submodule { freeformType = format.type; };
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
The configuration for the plugin.
|
||||||
|
|
||||||
|
The {option}`services.lavalink.plugins.*.configName` option must be set.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default = [ ];
|
||||||
|
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
[
|
||||||
|
{
|
||||||
|
dependency = "dev.lavalink.youtube:youtube-plugin:1.8.0";
|
||||||
|
repository = "https://maven.lavalink.dev/snapshots";
|
||||||
|
hash = lib.fakeHash;
|
||||||
|
configName = "youtube";
|
||||||
|
extraConfig = {
|
||||||
|
enabled = true;
|
||||||
|
allowSearch = true;
|
||||||
|
allowDirectVideoIds = true;
|
||||||
|
allowDirectPlaylistIds = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
|
||||||
|
description = ''
|
||||||
|
A list of plugins for lavalink.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.submodule { freeformType = format.type; };
|
||||||
|
|
||||||
|
description = ''
|
||||||
|
Configuration to write to {file}`application.yml`.
|
||||||
|
See <https://lavalink.dev/configuration/#example-applicationyml> for the full documentation.
|
||||||
|
|
||||||
|
Individual configuration parameters can be overwritten using environment variables.
|
||||||
|
See <https://lavalink.dev/configuration/#example-environment-variables> for more information.
|
||||||
|
'';
|
||||||
|
|
||||||
|
default = { };
|
||||||
|
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
lavalink.server = {
|
||||||
|
sources.twitch = true;
|
||||||
|
|
||||||
|
filters.volume = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
logging.file.path = "./logs/";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
pluginSymlinks = lib.concatStringsSep "\n" (
|
||||||
|
map (
|
||||||
|
pluginCfg:
|
||||||
|
let
|
||||||
|
pluginParts = lib.match ''^(.*?:(.*?):)([0-9]+\.[0-9]+\.[0-9]+)$'' pluginCfg.dependency;
|
||||||
|
|
||||||
|
pluginWebPath = lib.replaceStrings [ "." ":" ] [ "/" "/" ] (lib.elemAt pluginParts 0);
|
||||||
|
|
||||||
|
pluginFileName = lib.elemAt pluginParts 1;
|
||||||
|
pluginVersion = lib.elemAt pluginParts 2;
|
||||||
|
|
||||||
|
pluginFile = "${pluginFileName}-${pluginVersion}.jar";
|
||||||
|
pluginUrl = "${pluginCfg.repository}/${pluginWebPath}${pluginVersion}/${pluginFile}";
|
||||||
|
|
||||||
|
plugin = pkgs.fetchurl {
|
||||||
|
url = pluginUrl;
|
||||||
|
inherit (pluginCfg) hash;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
"ln -sf ${plugin} ${cfg.home}/plugins/${pluginFile}"
|
||||||
|
) cfg.plugins
|
||||||
|
);
|
||||||
|
|
||||||
|
pluginExtraConfigs = builtins.listToAttrs (
|
||||||
|
builtins.map (
|
||||||
|
pluginConfig: lib.attrsets.nameValuePair pluginConfig.configName pluginConfig.extraConfig
|
||||||
|
) (lib.lists.filter (pluginCfg: pluginCfg.configName != null) cfg.plugins)
|
||||||
|
);
|
||||||
|
|
||||||
|
config = lib.attrsets.recursiveUpdate cfg.extraConfig {
|
||||||
|
server = {
|
||||||
|
inherit (cfg) port address;
|
||||||
|
http2.enabled = cfg.enableHttp2;
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = pluginExtraConfigs;
|
||||||
|
lavalink.plugins = (
|
||||||
|
builtins.map (
|
||||||
|
pluginConfig:
|
||||||
|
builtins.removeAttrs pluginConfig [
|
||||||
|
"name"
|
||||||
|
"extraConfig"
|
||||||
|
"hash"
|
||||||
|
]
|
||||||
|
) cfg.plugins
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
configWithPassword = lib.attrsets.recursiveUpdate config (
|
||||||
|
lib.attrsets.optionalAttrs (cfg.password != null) { lavalink.server.password = cfg.password; }
|
||||||
|
);
|
||||||
|
|
||||||
|
configFile = format.generate "application.yml" configWithPassword;
|
||||||
|
in
|
||||||
|
mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion =
|
||||||
|
!(lib.lists.any (
|
||||||
|
pluginCfg: pluginCfg.extraConfig != { } && pluginCfg.configName == null
|
||||||
|
) cfg.plugins);
|
||||||
|
message = "Plugins with extra configuration need to have the `configName` attribute defined";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||||
|
|
||||||
|
users.groups = mkIf (cfg.group == "lavalink") { lavalink = { }; };
|
||||||
|
users.users = mkIf (cfg.user == "lavalink") {
|
||||||
|
lavalink = {
|
||||||
|
inherit (cfg) home;
|
||||||
|
group = "lavalink";
|
||||||
|
description = "The user for the Lavalink server";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.settings."10-lavalink" =
|
||||||
|
let
|
||||||
|
dirConfig = {
|
||||||
|
inherit (cfg) user group;
|
||||||
|
mode = "0700";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"${cfg.home}/plugins".d = mkIf (cfg.plugins != [ ]) dirConfig;
|
||||||
|
${cfg.home}.d = dirConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.lavalink = {
|
||||||
|
description = "Lavalink Service";
|
||||||
|
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [
|
||||||
|
"syslog.target"
|
||||||
|
"network.target"
|
||||||
|
];
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
${pluginSymlinks}
|
||||||
|
|
||||||
|
ln -sf ${configFile} ${cfg.home}/application.yml
|
||||||
|
export _JAVA_OPTIONS="${cfg.jvmArgs}"
|
||||||
|
|
||||||
|
${lib.getExe cfg.package}
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
|
||||||
|
Type = "simple";
|
||||||
|
Restart = "on-failure";
|
||||||
|
|
||||||
|
EnvironmentFile = cfg.environmentFile;
|
||||||
|
WorkingDirectory = cfg.home;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue