nixos/n8n: fix eval error with default values (#494127)

This commit is contained in:
Gergő Gutyina
2026-02-27 14:39:53 +00:00
committed by GitHub
2 changed files with 44 additions and 39 deletions
+7 -10
View File
@@ -10,8 +10,9 @@ let
# Partition environment variables into regular and file-based (_FILE suffix)
envVarToCredName = varName: lib.toLower varName;
partitionEnv =
env:
allEnv:
let
env = lib.filterAttrs (_name: value: value != null) allEnv;
regular = lib.filterAttrs (name: _value: !(lib.hasSuffix "_FILE" name)) env;
fileBased = lib.filterAttrs (name: _value: lib.hasSuffix "_FILE" name) env;
fileBasedTransformed = lib.mapAttrs' (
@@ -240,14 +241,6 @@ in
(coercedTo bool builtins.toJSON str)
]);
options = {
N8N_RUNNERS_CONFIG_PATH = lib.mkOption {
internal = true;
type = with lib.types; nullOr path;
default = launcherConfigFile;
description = ''
Path to the configuration file for the task runner launcher.
'';
};
N8N_RUNNERS_AUTH_TOKEN_FILE = lib.mkOption {
type = with lib.types; nullOr path;
default = cfg.environment.N8N_RUNNERS_AUTH_TOKEN_FILE;
@@ -401,7 +394,11 @@ in
after = [ "n8n.service" ];
requires = [ "n8n.service" ];
wantedBy = [ "multi-user.target" ];
environment = runnersEnv.regular // runnersEnv.fileBasedTransformed;
environment = {
N8N_RUNNERS_CONFIG_PATH = launcherConfigFile;
}
// runnersEnv.regular
// runnersEnv.fileBasedTransformed;
serviceConfig = {
Type = "simple";
ExecStart = "${lib.getExe runnersCfg.launcherPackage} ${lib.concatStringsSep " " runnerTypes}";
+37 -29
View File
@@ -16,9 +16,11 @@ in
node.pkgsReadOnly = false;
nodes.machine =
{ ... }:
{
nodes = {
machine_simple = {
services.n8n.enable = true;
};
machine_configured = {
services.n8n = {
enable = true;
customNodes = [ pkgs.n8n-nodes-carbonejs ];
@@ -49,52 +51,58 @@ in
};
};
};
};
testScript = ''
machine.wait_for_unit("n8n.service")
machine.wait_for_console_text("Editor is now accessible via")
machine_simple.wait_for_unit("n8n.service")
machine_simple.wait_for_console_text("Editor is now accessible via")
machine_simple.succeed("curl --fail -vvv http://localhost:${toString port}/")
machine_configured.wait_for_unit("n8n.service")
machine_configured.wait_for_console_text("Editor is now accessible via")
# Test regular environment variables
machine.succeed("curl --fail -vvv http://localhost:${toString port}/")
machine.succeed("grep -qF ${webhookUrl} /etc/systemd/system/n8n.service")
machine.succeed("grep -qF 'HOME=/var/lib/n8n' /etc/systemd/system/n8n.service")
machine.fail("grep -qF 'GENERIC_TIMEZONE=' /etc/systemd/system/n8n.service")
machine.succeed("grep -qF 'N8N_DIAGNOSTICS_ENABLED=false' /etc/systemd/system/n8n.service")
machine.succeed("grep -qF 'N8N_TEMPLATES_ENABLED=false' /etc/systemd/system/n8n.service")
machine.succeed("grep -qF 'DB_PING_INTERVAL_SECONDS=2' /etc/systemd/system/n8n.service")
machine_configured.succeed("curl --fail -vvv http://localhost:${toString port}/")
machine_configured.succeed("grep -qF ${webhookUrl} /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'HOME=/var/lib/n8n' /etc/systemd/system/n8n.service")
machine_configured.fail("grep -qF 'GENERIC_TIMEZONE=' /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'N8N_DIAGNOSTICS_ENABLED=false' /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'N8N_TEMPLATES_ENABLED=false' /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'DB_PING_INTERVAL_SECONDS=2' /etc/systemd/system/n8n.service")
# Test _FILE environment variables
machine.succeed("grep -qF 'LoadCredential=n8n_encryption_key_file:${secretFile}' /etc/systemd/system/n8n.service")
machine.succeed("grep -qF 'N8N_ENCRYPTION_KEY_FILE=%d/n8n_encryption_key_file' /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'LoadCredential=n8n_encryption_key_file:${secretFile}' /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'N8N_ENCRYPTION_KEY_FILE=%d/n8n_encryption_key_file' /etc/systemd/system/n8n.service")
# Test custom nodes
machine.succeed("grep -qF 'N8N_CUSTOM_EXTENSIONS=' /etc/systemd/system/n8n.service")
custom_extensions_dir = machine.succeed("grep -oP 'N8N_CUSTOM_EXTENSIONS=\\K[^\"]+' /etc/systemd/system/n8n.service").strip()
machine.succeed(f"test -L {custom_extensions_dir}/n8n-nodes-carbonejs")
machine.succeed(f"test -f {custom_extensions_dir}/n8n-nodes-carbonejs/package.json")
machine_configured.succeed("grep -qF 'N8N_CUSTOM_EXTENSIONS=' /etc/systemd/system/n8n.service")
custom_extensions_dir = machine_configured.succeed("grep -oP 'N8N_CUSTOM_EXTENSIONS=\\K[^\"]+' /etc/systemd/system/n8n.service").strip()
machine_configured.succeed(f"test -L {custom_extensions_dir}/n8n-nodes-carbonejs")
machine_configured.succeed(f"test -f {custom_extensions_dir}/n8n-nodes-carbonejs/package.json")
# Test task runner integration on n8n service
machine.succeed("grep -qF 'N8N_RUNNERS_MODE=external' /etc/systemd/system/n8n.service")
machine.succeed("grep -qF 'N8N_RUNNERS_BROKER_PORT=${toString brokerPort}' /etc/systemd/system/n8n.service")
machine.succeed("grep -qF 'LoadCredential=n8n_runners_auth_token_file:${authTokenFile}' /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'N8N_RUNNERS_MODE=external' /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'N8N_RUNNERS_BROKER_PORT=${toString brokerPort}' /etc/systemd/system/n8n.service")
machine_configured.succeed("grep -qF 'LoadCredential=n8n_runners_auth_token_file:${authTokenFile}' /etc/systemd/system/n8n.service")
# Test task runner service
machine.wait_for_unit("n8n-task-runner.service")
machine.succeed("systemctl is-active n8n-task-runner.service")
machine_configured.wait_for_unit("n8n-task-runner.service")
machine_configured.succeed("systemctl is-active n8n-task-runner.service")
# Test that both runner types are enabled
machine.succeed("grep -qF 'javascript python' /etc/systemd/system/n8n-task-runner.service")
machine_configured.succeed("grep -qF 'javascript python' /etc/systemd/system/n8n-task-runner.service")
# Test common environment variables are passed to launcher
machine.succeed("grep -qF 'N8N_RUNNERS_MAX_CONCURRENCY=10' /etc/systemd/system/n8n-task-runner.service")
machine.succeed("grep -qF 'N8N_RUNNERS_TASK_BROKER_URI=http://127.0.0.1:${toString brokerPort}' /etc/systemd/system/n8n-task-runner.service")
machine_configured.succeed("grep -qF 'N8N_RUNNERS_MAX_CONCURRENCY=10' /etc/systemd/system/n8n-task-runner.service")
machine_configured.succeed("grep -qF 'N8N_RUNNERS_TASK_BROKER_URI=http://127.0.0.1:${toString brokerPort}' /etc/systemd/system/n8n-task-runner.service")
# Test auth token is loaded via credentials
machine.succeed("grep -qF 'LoadCredential=n8n_runners_auth_token_file:${authTokenFile}' /etc/systemd/system/n8n-task-runner.service")
machine_configured.succeed("grep -qF 'LoadCredential=n8n_runners_auth_token_file:${authTokenFile}' /etc/systemd/system/n8n-task-runner.service")
# Test launcher config file
config_path = machine.succeed("grep -oP 'N8N_RUNNERS_CONFIG_PATH=\\K[^[:space:]\"]+' /etc/systemd/system/n8n-task-runner.service").strip()
config = machine.succeed(f"cat {config_path}")
config_path = machine_configured.succeed("grep -oP 'N8N_RUNNERS_CONFIG_PATH=\\K[^[:space:]\"]+' /etc/systemd/system/n8n-task-runner.service").strip()
config = machine_configured.succeed(f"cat {config_path}")
assert "NODE_FUNCTION_ALLOW_BUILTIN" in config, "JavaScript env-override not in config"
assert "N8N_RUNNERS_STDLIB_ALLOW" in config, "Python env-override not in config"
assert "N8N_RUNNERS_MAX_CONCURRENCY" in config, "Common allowed-env not in config"