inventory: expose finalSettings of every machine

This commit is contained in:
Johannes Kirschbauer
2025-10-19 18:01:50 +02:00
parent 3b070ae1f3
commit f96a487bc3
3 changed files with 145 additions and 71 deletions

View File

@@ -22,19 +22,15 @@ let
- roleName: The name of the role
- instanceName: The name of the instance
- settings: The settings of the machine. Leave empty to get the role settings
- : The settings of the machine. Leave empty to get the role settings
- modules: The settings of the machine. Leave empty to get the role settings
Returns: evalModules result
The caller is responsible to use .config or .extendModules
*/
evalMachineSettings =
{
roleName,
instanceName,
machineName ? null,
settings,
}:
instanceName: roleName: machineName: roleSettings: machineSettings:
lib.evalModules {
# Prefix for better error reporting
# This prints the path where the option should be defined rather than the plain path within settings
@@ -66,13 +62,8 @@ let
(lib.setDefaultModuleLocation "Via clan.service module: roles.${roleName}.interface"
config.roles.${roleName}.interface
)
(lib.setDefaultModuleLocation "instances.${instanceName}.roles.${roleName}.settings"
config.instances.${instanceName}.roles.${roleName}.settings
)
settings
# Dont set the module location here
# This should already be set by the tags resolver
# config.instances.${instanceName}.roles.${roleName}.machines.${machineName}.settings
(lib.setDefaultModuleLocation "Via clan.service module: instances.${instanceName}.roles.${roleName}.settings" roleSettings)
machineSettings
];
};
@@ -90,12 +81,9 @@ let
applySettings =
instanceName: instance:
lib.mapAttrs (roleName: role: {
machines = lib.mapAttrs (machineName: v: {
machines = lib.mapAttrs (machineName: _v: {
settings =
(evalMachineSettings {
inherit roleName instanceName machineName;
inherit (v) settings;
}).config;
config.instances.${instanceName}.roles.${roleName}.machines.${machineName}.finalSettings.config;
}) role.machines;
}) instance.roles;
in
@@ -137,7 +125,7 @@ in
elemType = submoduleWith {
modules = [
(
{ name, ... }:
{ name, ... }@instance:
{
options.roles = mkOption {
description = ''
@@ -167,7 +155,9 @@ in
placeholder = "roleName";
elemType = submoduleWith {
modules = [
({
(
{ name, ... }@role:
{
# instances.{instanceName}.roles.{roleName}.machines
options.machines = mkOption {
description = ''
@@ -185,13 +175,22 @@ in
placeholder = "machineName";
elemType = submoduleWith {
modules = [
(m: {
(
{ name, ... }@machine:
{
options.settings = mkOption {
type = types.raw;
description = "Settings of '${name}-machine': ${m.name or "<machineName>"}.";
description = "Settings of '${name}-machine': ${machine.name or "<machineName>"}.";
default = { };
};
})
options.finalSettings = mkOption {
default =
evalMachineSettings instance.name role.name machine.name role.config.settings
machine.config.settings;
type = types.raw;
};
}
)
];
};
};
@@ -211,7 +210,8 @@ in
default = [ ];
type = types.listOf (types.either types.deferredModule types.str);
};
})
}
)
];
};
};
@@ -549,16 +549,10 @@ in
roles = lib.attrNames (lib.filterAttrs (_n: v: v.machines ? ${machineName}) roles);
};
settings =
(evalMachineSettings {
inherit roleName instanceName machineName;
settings =
config.instances.${instanceName}.roles.${roleName}.machines.${machineName}.settings or { };
}).config;
extendSettings = extendEval (evalMachineSettings {
inherit roleName instanceName machineName;
settings =
config.instances.${instanceName}.roles.${roleName}.machines.${machineName}.settings or { };
});
config.instances.${instanceName}.roles.${roleName}.machines.${machineName}.finalSettings.config;
extendSettings =
extendEval
config.instances.${instanceName}.roles.${roleName}.machines.${machineName}.finalSettings;
};
modules = [ v ];
}).config;
@@ -589,10 +583,8 @@ in
<instanceName> = {
roles = {
<roleName> = {
# Per-machine settings
# Resolved per-machine settings
machines = { <machineName> = { settings = { ... }; }; }; };
# Per-role settings
settings = { ... };
};
};
};

View File

@@ -55,6 +55,7 @@ in
{
extraModules = import ./extraModules.nix { inherit clanLib; };
exports = import ./exports.nix { inherit lib clanLib; };
settings = import ./settings.nix { inherit lib callInventoryAdapter; };
resolve_module_spec = import ./import_module_spec.nix { inherit lib callInventoryAdapter; };
test_simple =
let

View File

@@ -0,0 +1,81 @@
{ callInventoryAdapter, lib, ... }:
let
res = callInventoryAdapter {
modules."A" = {
_class = "clan.service";
manifest = {
name = "network";
};
roles.peer.interface =
{ lib, ... }:
{
options.timeout = lib.mkOption {
type = lib.types.int;
};
};
roles.controller.interface =
{ lib, ... }:
{
options.maxPeers = lib.mkOption {
type = lib.types.int;
};
};
};
machines = {
jon = { };
sara = { };
};
instances."instance_foo" = {
module = {
name = "A";
input = "self";
};
# Settings for both jon and sara
roles.peer.settings = {
timeout = 40;
};
# Jon overrides timeout
roles.peer.machines.jon = {
settings.timeout = lib.mkForce 42;
};
roles.peer.machines.sara = { };
};
};
config = res.servicesEval.config.mappedServices.self-A;
#
applySettings =
instanceName: instance:
lib.mapAttrs (roleName: role: {
machines = lib.mapAttrs (machineName: _v: {
settings =
config.instances.${instanceName}.roles.${roleName}.machines.${machineName}.finalSettings.config;
}) role.machines;
}) instance.roles;
mapSettings = lib.mapAttrs applySettings config.instances;
in
{
test_simple = {
expr = mapSettings;
expected = {
instance_foo = {
peer = {
machines = {
jon = {
settings = {
timeout = 42;
};
};
sara = {
settings = {
timeout = 40;
};
};
};
};
};
};
};
}