Why can’t I reuse a variable from another module?
I have a source file (interfaces.json
) that I use as input to generate service definitions (corerad, avahi, dnsmasq…), which is working well but there’s a lot of repetition with variables between files.
Data should flow something like this: interfaces.json
→ interfaces.nix
→ corerad.nix
# First attempt, this is working today, but gen is redefined in
# every service file I have
{ lib, ... }:
let
# this line in particular gets repeated in all files
gen = builtins.fromJSON (builtins.readFile ../interfaces.json);
# file specific functions
guess_prefix = (addr: "${(lib.strings.removeSuffix "1/64" addr)}/64");
prefixAttr = (prefix: { prefix = prefix; });
intDefs = ({ name, ipv6, advertise ? false, ... }: {
name = name;
advertise = advertise;
rdnss = [{ servers = ["::"]; lifetime = "auto"; }];
prefix = builtins.map
(addr: prefixAttr (guess_prefix addr))
(builtins.attrValues ipv6);
});
in
{
services.corerad.enable = true;
services.corerad.settings = {
interfaces = builtins.map intDefs gen.interfaces;
};
}
So I then tried to create a file called interfaces.nix
and define the gen
variable there instead (but now calling it vars
due to reaons):
{ lib, ... }:
let
vars = builtins.fromJSON (builtins.readFile ./interfaces.json);
interfaceNames = lib.catAttrs "name" vars.interfaces;
ifAvahiAllowed = [ "eth0" "eth1" "eth2" ];
in {
inherit vars;
inherit interfaceNames;
inherit ifAvahiAllowed;
}
Then I tried to just use the vars
variable in corerad.nix
:
{lib, ... }:
let
# vars = import ../interfaces.nix {inherit lib;};
# interfaces = with vars; [interfaces];
# vars = pkgs.callPackage ../interfaces.nix {};
# interfaces = vars.interfaces;
# ints = with vars; [interfaces];
# ints = (import ../interfaces.nix interfaces);
# inherit (import ../interfaces.nix) vars;
varFile = import ../interfaces.nix;
vars = varFile.vars;
# vars = varFile.vars;
# inherit (import ../interfaces.nix) interfaces;
in {
# inherit vars;
services.corerad.enable = true;
services.corerad.settings = {
interfaces = builtins.map intDefs vars.interfaces;
};
}
…but getting this error message:
nixos-rebuild build
building Nix...
building the system configuration...
error:
… while calling the 'head' builtin
at /nix/store/53j9ijd4fgwj214wfpahkvf2ym97g8qg-nixos-23.11/nixos/lib/attrsets.nix:922:11:
921| || pred here (elemAt values 1) (head values) then
922| head values
| ^
923| else
… while evaluating the attribute 'value'
at /nix/store/53j9ijd4fgwj214wfpahkvf2ym97g8qg-nixos-23.11/nixos/lib/modules.nix:807:9:
806| in warnDeprecation opt //
807| { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
| ^
808| inherit (res.defsFinal') highestPrio;
(stack trace truncated; use '--show-trace' to show the full trace)
error: value is a function while a set was expected
What am I missing?
Also, this is an example of interfaces.json
:
{
"interfaces": [
{
"name": "example",
"vid": 100,
"ipv4": "192.168.0.1/24",
"ipv6": {
"ula": "fd0b:7c3c:2594::1/64",
"gua": "2001:db8:3333:4444:5555:6666:7777:8888"
},
"subnet": "192.168.0.0/24",
"dhcp-range": "192.168.0.100-192.168.0.200",
"domain": "home.arpa"
}
]
}