mirror of https://gitlab.crans.org/nounous/nixos
257 lines
8.6 KiB
Nix
257 lines
8.6 KiB
Nix
{
|
|
lib,
|
|
pkgs,
|
|
config,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.services.peertube-runner;
|
|
|
|
settingsFormat = pkgs.formats.toml { };
|
|
configFile = settingsFormat.generate "config.toml" cfg.settings;
|
|
|
|
env = {
|
|
NODE_ENV = "production";
|
|
XDG_CONFIG_HOME = "/var/lib/peertube-runner";
|
|
XDG_CACHE_HOME = "/var/cache/peertube-runner";
|
|
# peertube-runner makes its IPC socket in $XDG_DATA_HOME.
|
|
XDG_DATA_HOME = "/run/peertube-runner";
|
|
};
|
|
in
|
|
{
|
|
options.services.peertube-runner = {
|
|
enable = lib.mkEnableOption "peertube-runner";
|
|
package = lib.mkPackageOption pkgs [ "peertube" "runner" ] { };
|
|
|
|
user = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "prunner";
|
|
example = "peertube-runner";
|
|
description = "User account under which peertube-runner runs.";
|
|
};
|
|
group = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "prunner";
|
|
example = "peertube-runner";
|
|
description = "Group under which peertube-runner runs.";
|
|
};
|
|
|
|
settings = lib.mkOption {
|
|
type = settingsFormat.type;
|
|
default = { };
|
|
example = lib.literalExpression ''
|
|
{
|
|
jobs.concurrency = 4;
|
|
ffmpeg = {
|
|
threads = 0; # Let ffmpeg automatically choose.
|
|
nice = 5;
|
|
};
|
|
transcription.model = "large-v3";
|
|
}
|
|
'';
|
|
description = ''
|
|
Configuration for peertube-runner.
|
|
|
|
See available configuration options at https://docs.joinpeertube.org/maintain/tools#configuration.
|
|
'';
|
|
};
|
|
instancesToRegister = lib.mkOption {
|
|
type =
|
|
with lib.types;
|
|
attrsOf (submodule {
|
|
options = {
|
|
url = lib.mkOption {
|
|
type = lib.types.str;
|
|
example = "https://mypeertubeinstance.com";
|
|
description = "URL of the PeerTube instance.";
|
|
};
|
|
registrationTokenFile = lib.mkOption {
|
|
type = lib.types.path;
|
|
example = "/run/secrets/my-peertube-instance-registration-token";
|
|
description = ''
|
|
Path to a file containing a registration token for the PeerTube instance.
|
|
|
|
See how to generate registration tokens at https://docs.joinpeertube.org/admin/remote-runners#manage-remote-runners.
|
|
'';
|
|
};
|
|
runnerName = lib.mkOption {
|
|
type = lib.types.str;
|
|
example = "Transcription";
|
|
description = "Runner name declared to the PeerTube instance.";
|
|
};
|
|
runnerDescription = lib.mkOption {
|
|
type = with lib.types; nullOr str;
|
|
default = null;
|
|
example = "Runner for video transcription";
|
|
description = "Runner description declared to the PeerTube instance.";
|
|
};
|
|
};
|
|
});
|
|
default = { };
|
|
example = {
|
|
personal = {
|
|
url = "https://mypeertubeinstance.com";
|
|
registrationTokenFile = "/run/secrets/my-peertube-instance-registration-token";
|
|
runnerName = "Transcription";
|
|
runnerDescription = "Runner for video transcription";
|
|
};
|
|
};
|
|
description = "PeerTube instances to register this runner with.";
|
|
};
|
|
|
|
enabledJobTypes = lib.mkOption {
|
|
type = with lib.types; nonEmptyListOf str;
|
|
default = [
|
|
"vod-web-video-transcoding"
|
|
"vod-hls-transcoding"
|
|
"vod-audio-merge-transcoding"
|
|
"live-rtmp-hls-transcoding"
|
|
"video-studio-transcoding"
|
|
"video-transcription"
|
|
];
|
|
example = [ "video-transcription" ];
|
|
description = "Job types that this runner will execute.";
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
assertions = [
|
|
{
|
|
assertion = !(cfg.settings ? registeredInstances);
|
|
message = ''
|
|
`services.peertube-runner.settings.registeredInstances` cannot be used.
|
|
Instead, registered instances can be configured with `services.peertube-runner.instancesToRegister`.
|
|
'';
|
|
}
|
|
];
|
|
warnings = lib.optional (cfg.instancesToRegister == { }) ''
|
|
`services.peertube-runner.instancesToRegister` is empty.
|
|
Instances cannot be manually registered using the command line.
|
|
'';
|
|
|
|
services.peertube-runner.settings = {
|
|
transcription = lib.mkIf (lib.elem "video-transcription" cfg.enabledJobTypes) {
|
|
engine = lib.mkDefault "whisper-ctranslate2";
|
|
enginePath = lib.mkDefault (lib.getExe pkgs.whisper-ctranslate2);
|
|
};
|
|
};
|
|
|
|
environment.systemPackages = [
|
|
(pkgs.writeShellScriptBin "peertube-runner" ''
|
|
${lib.concatMapAttrsStringSep "\n" (name: value: ''export ${name}="${toString value}"'') env}
|
|
|
|
if [[ "$USER" == ${cfg.user} ]]; then
|
|
exec ${lib.getExe' cfg.package "peertube-runner"} "$@"
|
|
else
|
|
echo "This has to be run with the \`${cfg.user}\` user. Ex: \`sudo -u ${cfg.user} peertube-runner\`"
|
|
fi
|
|
'')
|
|
];
|
|
|
|
systemd.services.peertube-runner = {
|
|
description = "peertube-runner daemon";
|
|
after = [
|
|
"network.target"
|
|
(lib.mkIf config.services.peertube.enable "peertube.service")
|
|
];
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
environment = env;
|
|
path = [ pkgs.ffmpeg-headless ];
|
|
|
|
script = ''
|
|
config_dir=$XDG_CONFIG_HOME/peertube-runner-nodejs/default
|
|
mkdir -p $config_dir
|
|
config_file=$config_dir/config.toml
|
|
cp -f --no-preserve=mode,ownership ${configFile} $config_file
|
|
|
|
${lib.optionalString ((lib.length (lib.attrNames cfg.instancesToRegister)) > 0) ''
|
|
# Temp config directory for registration commands
|
|
temp_dir=$(mktemp --directory)
|
|
temp_config_dir=$temp_dir/peertube-runner-nodejs/default
|
|
mkdir -p $temp_config_dir
|
|
temp_config_file=$temp_config_dir/config.toml
|
|
|
|
mkdir -p $STATE_DIRECTORY/runner_tokens
|
|
${lib.concatMapAttrsStringSep "\n" (instanceName: instance: ''
|
|
runner_token_file=$STATE_DIRECTORY/runner_tokens/${instanceName}
|
|
|
|
# Register any currenctly unregistered instances.
|
|
if [ ! -f $runner_token_file ] || [[ $(cat $runner_token_file) != ptrt-* ]]; then
|
|
# Server has to be running for registration.
|
|
XDG_CONFIG_HOME=$temp_dir ${lib.getExe' cfg.package "peertube-runner"} server &
|
|
|
|
XDG_CONFIG_HOME=$temp_dir ${lib.getExe' cfg.package "peertube-runner"} register \
|
|
--url ${lib.escapeShellArg instance.url} \
|
|
--registration-token "$(cat ${instance.registrationTokenFile})" \
|
|
--runner-name ${lib.escapeShellArg instance.runnerName} \
|
|
${lib.optionalString (
|
|
instance.runnerDescription != null
|
|
) ''--runner-description ${lib.escapeShellArg instance.runnerDescription}''}
|
|
|
|
# Kill the server
|
|
kill $!
|
|
|
|
${lib.getExe pkgs.yq-go} -e ".registeredInstances[0].runnerToken" \
|
|
$temp_config_file > $runner_token_file
|
|
rm $temp_config_file
|
|
fi
|
|
|
|
echo "
|
|
|
|
[[registeredInstances]]
|
|
url = \"${instance.url}\"
|
|
runnerToken = \"$(cat $runner_token_file)\"
|
|
runnerName = \"${instance.runnerName}\"
|
|
${lib.optionalString (
|
|
instance.runnerDescription != null
|
|
) ''runnerDescription = \"${instance.runnerDescription}\"''}
|
|
" >> $config_file
|
|
'') cfg.instancesToRegister}
|
|
''}
|
|
|
|
# Don't allow changes that won't persist.
|
|
chmod 440 $config_file
|
|
|
|
systemd-notify --ready
|
|
exec ${lib.getExe' cfg.package "peertube-runner"} server ${
|
|
lib.concatMapStringsSep " " (jobType: "--enable-job ${jobType}") cfg.enabledJobTypes
|
|
}
|
|
'';
|
|
serviceConfig = {
|
|
Type = "notify";
|
|
NotifyAccess = "all"; # for systemd-notify
|
|
Restart = "always";
|
|
RestartSec = 5;
|
|
SyslogIdentifier = "prunner";
|
|
User = cfg.user;
|
|
Group = cfg.group;
|
|
StateDirectory = "peertube-runner";
|
|
StateDirectoryMode = "0700";
|
|
CacheDirectory = "peertube-runner";
|
|
CacheDirectoryMode = "0700";
|
|
RuntimeDirectory = "peertube-runner";
|
|
RuntimeDirectoryMode = "0700";
|
|
|
|
ProtectSystem = "full";
|
|
NoNewPrivileges = true;
|
|
ProtectHome = true;
|
|
CapabilityBoundingSet = "~CAP_SYS_ADMIN";
|
|
};
|
|
};
|
|
|
|
users.users = lib.mkIf (cfg.user == "prunner") {
|
|
${cfg.user} = {
|
|
isSystemUser = true;
|
|
group = cfg.group;
|
|
};
|
|
};
|
|
users.groups = lib.mkIf (cfg.group == "prunner") {
|
|
${cfg.group} = { };
|
|
};
|
|
};
|
|
|
|
meta.maintainers = lib.teams.ngi.members;
|
|
}
|