feat(inventory/instances): add option for extraModules to roles

This commit is contained in:
Johannes Kirschbauer
2025-06-03 17:39:17 +02:00
parent 97d7c38ba7
commit c6947a8fab
3 changed files with 83 additions and 4 deletions

View File

@@ -410,6 +410,48 @@ in
default = { }; default = { };
type = clanLib.types.uniqueDeferredSerializableModule; type = clanLib.types.uniqueDeferredSerializableModule;
}; };
extraModules = lib.mkOption {
description = ''
List of additionally imported `.nix` expressions.
Supported types:
- **Strings**: Interpreted relative to the 'directory' passed to buildClan.
- **Paths**: should be relative to the current file.
- **Any**: Nix expression must be serializable to JSON.
!!! Note
**The import only happens if the machine is part of the service or role.**
Other types are passed through to the nixos configuration.
???+ Example
To import the `special.nix` file
```
. Clan Directory
flake.nix
...
modules
special.nix
...
```
```nix
{
extraModules = [ "modules/special.nix" ];
}
```
'';
apply = value: if lib.isString value then value else builtins.seq (builtins.toJSON value) value;
default = [ ];
type = types.listOf (
types.oneOf [
types.str
types.anything
]
);
};
}; };
} }
); );

View File

@@ -188,7 +188,7 @@ in
# This is the list of nixosModules for each machine # This is the list of nixosModules for each machine
machineImports = lib.foldlAttrs ( machineImports = lib.foldlAttrs (
acc: _module_ident: eval: acc: _module_ident: eval:
acc ++ [ eval.config.result.final.${machineName}.nixosModule or {}] acc ++ [ eval.config.result.final.${machineName}.nixosModule or { } ]
) [ ] importedModulesEvaluated; ) [ ] importedModulesEvaluated;
}) inventory.machines; }) inventory.machines;
in in

View File

@@ -214,6 +214,11 @@ in
description = "Settings of 'role': ${name}"; description = "Settings of 'role': ${name}";
default = { }; default = { };
}; };
options.extraModules = lib.mkOption {
default = [ ];
type = types.listOf (types.deferredModule);
};
} }
) )
]; ];
@@ -405,12 +410,43 @@ in
# Intermediate result by mapping over the 'roles', 'instances', and 'machines'. # Intermediate result by mapping over the 'roles', 'instances', and 'machines'.
# During this step the 'perMachine' and 'perInstance' are applied. # During this step the 'perMachine' and 'perInstance' are applied.
# The result-set for a single machine can then be found by collecting all 'nixosModules' recursively. # The result-set for a single machine can then be found by collecting all 'nixosModules' recursively.
/**
allRoles :: {
<roleName> :: {
allInstances :: {
<instanceName> :: {
allMachines :: {
<machineName> :: {
nixosModule :: NixOSModule;
services :: { }; # TODO: nested services
};
};
};
};
};
}
*/
result.allRoles = mkOption { result.allRoles = mkOption {
readOnly = true; readOnly = true;
default = lib.mapAttrs (roleName: roleCfg: { default = lib.mapAttrs (roleName: roleCfg: {
allInstances = lib.mapAttrs (instanceName: instanceCfg: { allInstances = lib.mapAttrs (instanceName: instanceCfg: {
allMachines = lib.mapAttrs ( allMachines = lib.mapAttrs (
machineName: _machineCfg: roleCfg.perInstance instanceName machineName machineName: _machineCfg:
let
instanceRes = roleCfg.perInstance instanceName machineName;
in
{
nixosModule = {
imports = [
# Result of the applied 'perInstance = {...}: { nixosModule = { ... }; }'
instanceRes.nixosModule
] ++ instanceCfg.roles.${roleName}.extraModules;
};
# TODO: nested services
services = { };
}
) instanceCfg.roles.${roleName}.machines or { }; ) instanceCfg.roles.${roleName}.machines or { };
}) config.instances; }) config.instances;
}) config.roles; }) config.roles;
@@ -434,6 +470,9 @@ in
) [ ] instance.roles ) [ ] instance.roles
); );
# The service machines are defined by collecting all instance machines # The service machines are defined by collecting all instance machines
# returns "allMachines" that are part of the service in the form:
# serviceMachines :: { ${machineName} :: MachineOrigin; }
# MachineOrigin :: { instances :: [ string ]; roles :: [ string ]; }
serviceMachines = lib.foldlAttrs ( serviceMachines = lib.foldlAttrs (
acc: instanceName: instance: acc: instanceName: instance:
acc acc
@@ -470,8 +509,6 @@ in
default = lib.mapAttrs ( default = lib.mapAttrs (
machineName: machineResult: machineName: machineResult:
let let
# config.result.allRoles.client.allInstances.bar.allMachines.test
# instanceResults = config.result.allRoles.client.allInstances.bar.allMachines.${machineName};
instanceResults = lib.foldlAttrs ( instanceResults = lib.foldlAttrs (
acc: roleName: role: acc: roleName: role:
acc acc