Merge pull request 'chore(inventory/services): dont check _class in our logics. Let the error eccour in the final evaluation.' (#3236) from hsjobeki/clan-core:role-settings into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3236
This commit is contained in:
hsjobeki
2025-04-08 19:49:46 +00:00
8 changed files with 51 additions and 67 deletions

View File

@@ -56,7 +56,7 @@ let
assertions = { }; assertions = { };
}; };
legacyResolveImports = resolveImports =
{ {
supportedRoles, supportedRoles,
resolvedRolesPerInstance, resolvedRolesPerInstance,
@@ -168,36 +168,16 @@ in
./roles.nix ./roles.nix
]; ];
isClanModule = machineImports = resolveImports {
let supportedRoles = config.supportedRoles;
firstRole = import (getRoleFile (builtins.head config.supportedRoles)); resolvedRolesPerInstance = config.resolvedRolesPerInstance;
loadModuleForClassCheck = inherit
m: serviceConfigs
if lib.isFunction m then serviceName
let machineName
args = lib.functionArgs m; getRoleFile
in ;
m args };
else
m;
module = loadModuleForClassCheck (firstRole);
in
if (module) ? _class then module._class == "clan" else false;
# The actual result
machineImports =
if config.isClanModule then
throw "Clan modules are not supported yet."
else
legacyResolveImports {
supportedRoles = config.supportedRoles;
resolvedRolesPerInstance = config.resolvedRolesPerInstance;
inherit
serviceConfigs
serviceName
machineName
getRoleFile
;
};
# Assertions # Assertions
assertions = { assertions = {

View File

@@ -54,9 +54,6 @@ in
matchedRoles = mkOption { matchedRoles = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
}; };
isClanModule = mkOption {
type = types.bool;
};
machinesRoles = mkOption { machinesRoles = mkOption {
type = types.attrsOf (types.listOf types.str); type = types.attrsOf (types.listOf types.str);
}; };

View File

@@ -14,7 +14,7 @@ in
{ {
# Roles resolution # Roles resolution
# : List String # : List String
supportedRoles = clanLib.modules.getRoles inventory.modules serviceName; supportedRoles = clanLib.modules.getRoles "inventory.modules" inventory.modules serviceName;
matchedRoles = builtins.attrNames ( matchedRoles = builtins.attrNames (
lib.filterAttrs (_: ms: builtins.elem machineName ms) config.machinesRoles lib.filterAttrs (_: ms: builtins.elem machineName ms) config.machinesRoles
); );

View File

@@ -120,22 +120,13 @@ let
# TODO: Eagerly check the _class of the resolved module # TODO: Eagerly check the _class of the resolved module
importedModulesEvaluated = lib.mapAttrs ( importedModulesEvaluated = lib.mapAttrs (
_module_ident: instances: _module_ident: instances:
let
matchedClass = "clan.service";
instance = (builtins.head instances).instance;
classCheckedModule =
if instance.moduleClass == matchedClass then
instance.resolvedModule
else
(throw ''Module '${instance.module.name}' is not a valid '${matchedClass}' module. Got module with class:${builtins.toJSON instance.moduleClass}'');
in
(lib.evalModules { (lib.evalModules {
class = matchedClass; class = "clan.service";
modules = modules =
[ [
./service-module.nix ./service-module.nix
# Import the resolved module # Import the resolved module.
classCheckedModule (builtins.head instances).instance.resolvedModule
] ]
# Include all the instances that correlate to the resolved module # Include all the instances that correlate to the resolved module
++ (builtins.map (v: { ++ (builtins.map (v: {

View File

@@ -53,13 +53,4 @@ in
}; };
}; };
}; };
# Currently this should fail
# TODO: Can we implement a default wrapper to make migration easy?
test_import_local_legacy_module = {
expr = (resolve { name = "B"; }).allMachines;
expectedError = {
type = "ThrownError";
msg = "Module 'B' is not a valid 'clan.service' module.*";
};
};
} }

View File

@@ -74,7 +74,7 @@ let
roles = roles =
if builtins.elem "inventory" frontmatter.features or [ ] then if builtins.elem "inventory" frontmatter.features or [ ] then
assert lib.isPath module; assert lib.isPath module;
clanLib.modules.getRoles allModules moduleName clan-core.lib.modules.getRoles "Documentation: inventory.modules" allModules moduleName
else else
[ ]; [ ];
in in

View File

@@ -36,7 +36,7 @@ let
lib.evalModules { lib.evalModules {
specialArgs = { specialArgs = {
inherit moduleName resolvedRoles instanceName; inherit moduleName resolvedRoles instanceName;
allRoles = getRoles allModules moduleName; allRoles = getRoles "inventory.modules" allModules moduleName;
}; };
modules = [ modules = [
(getFrontmatter allModules.${moduleName} moduleName) (getFrontmatter allModules.${moduleName} moduleName)
@@ -56,16 +56,42 @@ let
]; ];
}).options; }).options;
# This is a legacy function
# Old modules needed to define their roles by directory
# This means if this function gets anything other than a string/path it will throw
getRoles = getRoles =
allModules: serviceName: scope: allModules: serviceName:
lib.mapAttrsToList (name: _value: trimExtension name) ( let
module =
allModules.${serviceName}
or (throw "(Legacy) ClanModule not found: '${serviceName}'. Make sure the module is added to ${scope}");
moduleType = (lib.typeOf module);
checked =
if
builtins.elem moduleType [
"string"
"path"
]
then
true
else
throw "(Legacy) ClanModule must be a 'path' or 'string' pointing to a directory: Got 'typeOf inventory.modules.${serviceName}' => ${moduleType} ";
modulePath = lib.seq checked module + "/roles";
checkedPath =
if builtins.pathExists modulePath then
modulePath
else
throw ''
(Legacy) ClanModule must have a 'roles' directory'
Fixes:
- Provide a 'roles' subdirectory
- Use the newer 'clan.service' modules. (Recommended)
'';
in
lib.seq checkedPath lib.mapAttrsToList (name: _value: trimExtension name) (
lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) ( lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) (
builtins.readDir ( builtins.readDir (checkedPath)
if allModules ? ${serviceName} then
allModules.${serviceName} + "/roles"
else
throw "ClanModule not found: '${serviceName}'. Make sure the module is added in the 'clanModules' attribute of clan-core."
)
) )
); );

View File

@@ -34,7 +34,6 @@ in
}; };
expected = { expected = {
legacyModule = { legacyModule = {
isClanModule = false;
}; };
}; };
}; };