diff --git a/nixos/modules/services/web-apps/invidious.nix b/nixos/modules/services/web-apps/invidious.nix index 2b93e942896c..29ec8c8ef9b1 100644 --- a/nixos/modules/services/web-apps/invidious.nix +++ b/nixos/modules/services/web-apps/invidious.nix @@ -7,16 +7,19 @@ }: let cfg = config.services.invidious; - # To allow injecting secrets with jq, json (instead of yaml) is used - settingsFormat = pkgs.formats.json { }; + inherit (lib) types; + # This need to be JSON to reduce number of + # breaking changes, for backwards + # compatibility with pre-25.11 + settingsFormat = pkgs.formats.json { }; settingsFile = settingsFormat.generate "invidious-settings" cfg.settings; generatedHmacKeyFile = "/var/lib/invidious/hmac_key"; generateHmac = cfg.hmacKeyFile == null; - commonInvidousServiceConfig = { + commonInvidiousServiceConfig = { description = "Invidious (An alternative YouTube front-end)"; wants = [ "network-online.target" ]; after = [ "network-online.target" ] ++ lib.optional cfg.database.createLocally "postgresql.target"; @@ -59,9 +62,51 @@ let RuntimeRandomizedExtraSec = lib.mkDefault "5min"; }; }; + + configScript = + scaleIndex: + '' + configParts=() + '' + # autogenerated hmac_key + + lib.optionalString generateHmac '' + configParts+=("$(${pkgs.jq}/bin/jq -R '{"hmac_key":.}' <"${generatedHmacKeyFile}")") + '' + # generated settings file + + '' + configParts+=("$(< ${settingsFile})") + '' + # optional database password file + + lib.optionalString (cfg.database.host != null) '' + configParts+=("$(${pkgs.jq}/bin/jq -R '{"db":{"password":.}}' ${cfg.database.passwordFile})") + '' + # optional extra settings file + + lib.optionalString (cfg.extraSettingsFile != null) '' + configParts+=("$(< ${lib.escapeShellArg cfg.extraSettingsFile})") + '' + # explicitly specified hmac key file + + lib.optionalString (cfg.hmacKeyFile != null) '' + configParts+=("$(< ${lib.escapeShellArg cfg.hmacKeyFile})") + '' + # configure threads for secondary instances + + lib.optionalString (scaleIndex > 0) '' + configParts+=('{"channel_threads":0, "feed_threads":0}') + '' + # configure different ports for the instances + + '' + configParts+=('{"port":${toString (cfg.port + scaleIndex)}}') + '' + # merge all parts into a single configuration with later elements overriding previous elements + + '' + mergedConfig="$(${pkgs.jq}/bin/jq -s 'reduce .[] as $item ({}; . * $item)' <<<"''${configParts[*]}")" + export INVIDIOUS_CONFIG=$(echo "$mergedConfig" | ${pkgs.yq-go}/bin/yq -P) + + exec ${cfg.package}/bin/invidious + ''; + mkInvidiousService = scaleIndex: - lib.foldl' lib.recursiveUpdate commonInvidousServiceConfig [ + lib.foldl' lib.recursiveUpdate commonInvidiousServiceConfig [ # only generate the hmac file in the first service (lib.optionalAttrs (scaleIndex == 0) { preStart = lib.optionalString generateHmac '' @@ -73,47 +118,10 @@ let }) # configure the secondary services to run after the first service (lib.optionalAttrs (scaleIndex > 0) { - after = commonInvidousServiceConfig.after ++ [ "invidious.service" ]; - wants = commonInvidousServiceConfig.wants ++ [ "invidious.service" ]; + after = commonInvidiousServiceConfig.after ++ [ "invidious.service" ]; + wants = commonInvidiousServiceConfig.wants ++ [ "invidious.service" ]; }) - { - script = '' - configParts=() - '' - # autogenerated hmac_key - + lib.optionalString generateHmac '' - configParts+=("$(${pkgs.jq}/bin/jq -R '{"hmac_key":.}' <"${generatedHmacKeyFile}")") - '' - # generated settings file - + '' - configParts+=("$(< ${lib.escapeShellArg settingsFile})") - '' - # optional database password file - + lib.optionalString (cfg.database.host != null) '' - configParts+=("$(${pkgs.jq}/bin/jq -R '{"db":{"password":.}}' ${lib.escapeShellArg cfg.database.passwordFile})") - '' - # optional extra settings file - + lib.optionalString (cfg.extraSettingsFile != null) '' - configParts+=("$(< ${lib.escapeShellArg cfg.extraSettingsFile})") - '' - # explicitly specified hmac key file - + lib.optionalString (cfg.hmacKeyFile != null) '' - configParts+=("$(< ${lib.escapeShellArg cfg.hmacKeyFile})") - '' - # configure threads for secondary instances - + lib.optionalString (scaleIndex > 0) '' - configParts+=('{"channel_threads":0, "feed_threads":0}') - '' - # configure different ports for the instances - + '' - configParts+=('{"port":${toString (cfg.port + scaleIndex)}}') - '' - # merge all parts into a single configuration with later elements overriding previous elements - + '' - export INVIDIOUS_CONFIG="$(${pkgs.jq}/bin/jq -s 'reduce .[] as $item ({}; . * $item)' <<<"''${configParts[*]}")" - exec ${cfg.package}/bin/invidious - ''; - } + { script = configScript scaleIndex; } ]; serviceConfig = {