Skip to content

Commit

Permalink
nixos/marytts: init module
Browse files Browse the repository at this point in the history
  • Loading branch information
pluiedev committed Nov 5, 2024
1 parent b637ab6 commit 8ec1585
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 0 deletions.
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2411.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@

- [tiny-dfr](https://github.com/WhatAmISupposedToPutHere/tiny-dfr), a dynamic function row daemon for the Touch Bar found on some Apple laptops. Available as [hardware.apple.touchBar.enable](options.html#opt-hardware.apple.touchBar.enable).

- [MaryTTS](https://github.com/marytts/marytts), an open-source, multilingual text-to-speech synthesis system written in pure Java. Available as [services.marytts](options.html#opt-services.marytts).

## Backward Incompatibilities {#sec-release-24.11-incompatibilities}

- The `sound` options have been removed or renamed, as they had a lot of unintended side effects. See [below](#sec-release-24.11-migration-sound) for details.
Expand Down
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@
./services/audio/jack.nix
./services/audio/jmusicbot.nix
./services/audio/liquidsoap.nix
./services/audio/marytts.nix
./services/audio/mopidy.nix
./services/audio/mpd.nix
./services/audio/mpdscribble.nix
Expand Down
164 changes: 164 additions & 0 deletions nixos/modules/services/audio/marytts.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.marytts;
format = pkgs.formats.javaProperties { };

maryBase = "/var/lib/marytts";
in
{
options.services.marytts = {
enable = lib.mkEnableOption "MaryTTS";

settings = lib.mkOption {
type = lib.types.submodule {
freeformType = format.type;
};
default = { };
description = ''
Settings for MaryTTS.
See the [default settings](https://github.com/marytts/marytts/blob/master/marytts-runtime/conf/marybase.config)
for a list of possible keys.
'';
};

port = lib.mkOption {
type = lib.types.port;
default = 59125;
description = ''
Port to bind the MaryTTS server to.
'';
};

openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = ''
Whether to open the port in the firewall for MaryTTS.
'';
};

voices = lib.mkOption {
type = lib.types.listOf lib.types.path;
default = [ ];
example = lib.literalExpression ''
[
(pkgs.fetchzip {
url = "https://github.com/marytts/voice-bits1-hsmm/releases/download/v5.2/voice-bits1-hsmm-5.2.zip";
hash = "sha256-1nK+qZxjumMev7z5lgKr660NCKH5FDwvZ9sw/YYYeaA=";
})
]
'';
description = ''
Paths to the JAR files that contain additional voices for MaryTTS.
Voices are automatically detected by MaryTTS, so there is no need to alter
your config to make use of new voices.
'';
};

userDictionaries = lib.mkOption {
type = lib.types.listOf lib.types.path;
default = [ ];
example = lib.literalExpression ''
[
(pkgs.writeTextFile {
name = "userdict-en_US";
destination = "/userdict-en_US.txt";
text = '''
Nixpkgs | n I k s - ' p { - k @ - dZ @ s
''';
})
]
'';
description = ''
Paths to the user dictionary files for MaryTTS.
'';
};
};

config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.marytts ];

systemd.services.marytts = {
description = "MaryTTS server instance";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];

script = "${lib.getExe pkgs.marytts} -Dsocket.port=${toString cfg.port}";

serviceConfig = {
DynamicUser = true;
User = "marytts";
RuntimeDirectory = "marytts";
StateDirectory = "marytts";
Restart = "on-failure";
RestartSec = 5;
TimeoutSec = 20;

# Hardening
ProtectClock = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
ProtectKernelModules = true;
ProtectHostname = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectHome = true;
ProcSubset = "pid";

PrivateTmp = true;
PrivateNetwork = false;
PrivateUsers = cfg.port >= 1024;
PrivateDevices = true;

RestrictRealtime = true;
RestrictNamespaces = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];

MemoryDenyWriteExecute = false; # Java does not like w^x :(
LockPersonality = true;
AmbientCapabilities = lib.optional (cfg.port < 1024) "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = lib.optional (cfg.port < 1024) "CAP_NET_BIND_SERVICE";
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@resources"
"~@privileged"
];
UMask = "0027";
};
};

systemd.tmpfiles.settings."10-marytts" = {
"${maryBase}/lib"."L+".argument = "${pkgs.symlinkJoin {
name = "marytts-voices";
# Put user paths before default ones so that user ones have priority
paths = cfg.voices ++ [ "${pkgs.marytts}/lib" ];
}}";

"${maryBase}/user-dictionaries"."L+".argument = "${pkgs.symlinkJoin {
name = "marytts-user-dictionaries";
# Put user paths before default ones so that user ones have priority
paths = cfg.userDictionaries ++ [ "${pkgs.marytts}/user-dictionaries" ];
}}";

"${maryBase}/conf/marybase.config"."L+".argument = "${format.generate "marybase.config" cfg.settings}";
};

networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.port ];
};
};
}

0 comments on commit 8ec1585

Please sign in to comment.