nix-config/modules/distributed-config.nix

82 lines
1.8 KiB
Nix
Raw Normal View History

{
config,
lib,
nodes,
...
2024-07-26 22:12:48 +02:00
}:
let
inherit (lib)
attrNames
concatMap
concatStringsSep
foldl'
getAttrFromPath
mkMerge
mkOption
mkOptionType
optionals
recursiveUpdate
setAttrByPath
types
;
nodeName = config.node.name;
2024-07-26 22:12:48 +02:00
mkForwardedOption =
path:
mkOption {
type = mkOptionType {
name = "Same type that the receiving option `${concatStringsSep "." path}` normally accepts.";
2024-07-26 22:12:48 +02:00
merge =
_loc: defs:
builtins.filter (x: builtins.isAttrs x -> ((x._type or "") != "__distributed_config_empty")) (
map (x: x.value) defs
);
};
default = {
_type = "__distributed_config_empty";
};
description = ''
Anything specified here will be forwarded to `${concatStringsSep "." path}`
on the given node. Forwarding happens as-is to the raw values,
so validity can only be checked on the receiving node.
'';
};
forwardedOptions = [
2024-07-26 22:12:48 +02:00
[
"age"
"secrets"
]
[
"services"
"maddy"
"ensureCredentials"
]
];
2024-07-26 22:12:48 +02:00
attrsForEachOption =
f: (foldl' (acc: path: recursiveUpdate acc (setAttrByPath path (f path))) { } forwardedOptions);
in
{
options.nodes = mkOption {
description = "Options forwareded to the given node.";
2024-07-26 22:12:48 +02:00
default = { };
type = types.attrsOf (types.submodule { options = attrsForEachOption mkForwardedOption; });
};
2024-07-26 22:12:48 +02:00
config =
let
mergeConfigFromOthers =
let
getConfig =
path: otherNode:
let
cfg = nodes.${otherNode}.config.nodes.${nodeName} or null;
in
optionals (cfg != null) (getAttrFromPath path cfg);
in
path: mkMerge (concatMap (getConfig path) (attrNames nodes));
in
attrsForEachOption mergeConfigFromOthers;
}