Inventory: init external modules support

This commit is contained in:
Johannes Kirschbauer
2024-11-21 11:45:31 +01:00
committed by hsjobeki
parent 604c16c30f
commit 25fb899f64
7 changed files with 37 additions and 27 deletions

View File

@@ -102,6 +102,7 @@ in
# We don't specify the type here, for better performance. # We don't specify the type here, for better performance.
inventory = lib.mkOption { type = lib.types.raw; }; inventory = lib.mkOption { type = lib.types.raw; };
inventoryFile = lib.mkOption { type = lib.types.raw; }; inventoryFile = lib.mkOption { type = lib.types.raw; };
serviceConfigs = lib.mkOption { type = lib.types.raw; };
clanModules = lib.mkOption { type = lib.types.raw; }; clanModules = lib.mkOption { type = lib.types.raw; };
source = lib.mkOption { type = lib.types.raw; }; source = lib.mkOption { type = lib.types.raw; };
meta = lib.mkOption { type = lib.types.raw; }; meta = lib.mkOption { type = lib.types.raw; };

View File

@@ -159,7 +159,7 @@ in
inventory.machines = lib.mapAttrs (_n: _: { }) config.machines; inventory.machines = lib.mapAttrs (_n: _: { }) config.machines;
} }
# Merge the meta attributes from the buildClan function # Merge the meta attributes from the buildClan function
# { inventory.modules = clan-core.clanModules; }
# config.inventory.meta <- config.meta # config.inventory.meta <- config.meta
{ inventory.meta = config.meta; } { inventory.meta = config.meta; }
# Set default for computed tags # Set default for computed tags
@@ -169,6 +169,7 @@ in
inherit nixosConfigurations; inherit nixosConfigurations;
clanInternals = { clanInternals = {
inherit serviceConfigs;
inherit (clan-core) clanModules; inherit (clan-core) clanModules;
inherit inventoryFile; inherit inventoryFile;
inventory = config.inventory; inventory = config.inventory;

View File

@@ -16,5 +16,5 @@ in
facts = import ./facts.nix { inherit lib; }; facts = import ./facts.nix { inherit lib; };
inventory = import ./inventory { inherit lib clan-core; }; inventory = import ./inventory { inherit lib clan-core; };
jsonschema = import ./jsonschema { inherit lib; }; jsonschema = import ./jsonschema { inherit lib; };
modules = import ./frontmatter { inherit clan-core lib; }; modules = import ./frontmatter { inherit lib; };
} }

View File

@@ -53,7 +53,7 @@ let
} }
*/ */
evalClanModulesWithRoles = evalClanModulesWithRoles =
clanModules: allModules:
let let
res = builtins.mapAttrs ( res = builtins.mapAttrs (
moduleName: module: moduleName: module:
@@ -62,7 +62,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;
clan-core.lib.modules.getRoles moduleName clan-core.lib.modules.getRoles allModules moduleName
else else
[ ]; [ ];
in in
@@ -83,7 +83,7 @@ let
}).options.clan.${moduleName} or { }; }).options.clan.${moduleName} or { };
}) roles }) roles
) )
) clanModules; ) allModules;
in in
res; res;
in in

View File

@@ -1,4 +1,4 @@
{ clan-core, lib }: { lib }:
let let
# Trim the .nix extension from a filename # Trim the .nix extension from a filename
trimExtension = name: builtins.substring 0 (builtins.stringLength name - 4) name; trimExtension = name: builtins.substring 0 (builtins.stringLength name - 4) name;
@@ -8,18 +8,20 @@ let
moduleName, moduleName,
instanceName, instanceName,
resolvedRoles, resolvedRoles,
allModules,
}: }:
lib.evalModules { lib.evalModules {
specialArgs = { specialArgs = {
inherit moduleName resolvedRoles instanceName; inherit moduleName resolvedRoles instanceName;
allRoles = getRoles moduleName; allRoles = getRoles allModules moduleName;
}; };
modules = [ modules = [
(getFrontmatter moduleName) (getFrontmatter allModules.${moduleName} moduleName)
./interface.nix ./interface.nix
]; ];
}; };
# For Documentation purposes only
frontmatterOptions = frontmatterOptions =
(lib.evalModules { (lib.evalModules {
specialArgs = { specialArgs = {
@@ -32,26 +34,24 @@ let
}).options; }).options;
getRoles = getRoles =
serviceName: allModules: serviceName:
lib.mapAttrsToList (name: _value: trimExtension name) ( 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 (
if clan-core.clanModules ? ${serviceName} then if allModules ? ${serviceName} then
clan-core.clanModules.${serviceName} + "/roles" allModules.${serviceName} + "/roles"
else else
throw "ClanModule not found: '${serviceName}'. Make sure the module is added in the 'clanModules' attribute of clan-core." throw "ClanModule not found: '${serviceName}'. Make sure the module is added in the 'clanModules' attribute of clan-core."
) )
) )
); );
getConstraints = modulename: (getFrontmatter modulename).constraints;
checkConstraints = args: (evalFrontmatter args).config.constraints.assertions; checkConstraints = args: (evalFrontmatter args).config.constraints.assertions;
getReadme = getReadme =
modulename: modulepath: modulename:
let let
readme = "${clan-core}/clanModules/${modulename}/README.md"; readme = modulepath + "/README.md";
readmeContents = readmeContents =
if (builtins.pathExists readme) then if (builtins.pathExists readme) then
(builtins.readFile readme) (builtins.readFile readme)
@@ -61,9 +61,9 @@ let
readmeContents; readmeContents;
getFrontmatter = getFrontmatter =
modulename: modulepath: modulename:
let let
content = getReadme modulename; content = getReadme modulepath modulename;
parts = lib.splitString "---" content; parts = lib.splitString "---" content;
# Partition the parts into the first part (the readme content) and the rest (the metadata) # Partition the parts into the first part (the readme content) and the rest (the metadata)
parsed = builtins.partition ({ index, ... }: if index >= 2 then false else true) ( parsed = builtins.partition ({ index, ... }: if index >= 2 then false else true) (
@@ -89,12 +89,10 @@ let
in in
{ {
inherit inherit
evalFrontmatter
frontmatterOptions frontmatterOptions
getFrontmatter getFrontmatter
getReadme
getConstraints
checkConstraints checkConstraints
getRoles getRoles
; ;

View File

@@ -38,8 +38,9 @@ let
}; };
checkService = checkService =
serviceName: modulepath: serviceName:
builtins.elem "inventory" (clan-core.lib.modules.getFrontmatter serviceName).features or [ ]; builtins.elem "inventory"
(clan-core.lib.modules.getFrontmatter modulepath serviceName).features or [ ];
extendMachine = extendMachine =
{ machineConfig, inventory }: { machineConfig, inventory }:
@@ -53,7 +54,7 @@ let
acc acc
++ [ ++ [
{ {
assertion = checkService serviceName; assertion = checkService inventory.modules.${serviceName} serviceName;
message = '' message = ''
Service ${serviceName} cannot be used in inventory. It does not declare the 'inventory' feature. Service ${serviceName} cannot be used in inventory. It does not declare the 'inventory' feature.
@@ -94,7 +95,7 @@ let
acc2: instanceName: serviceConfig: acc2: instanceName: serviceConfig:
let let
roles = clan-core.lib.modules.getRoles serviceName; roles = clan-core.lib.modules.getRoles inventory.modules serviceName;
resolvedRoles = lib.genAttrs roles ( resolvedRoles = lib.genAttrs roles (
roleName: roleName:
@@ -129,11 +130,11 @@ let
# TODO: maybe optimize this dont lookup the role in inverse roles. Imports are not lazy # TODO: maybe optimize this dont lookup the role in inverse roles. Imports are not lazy
roleModules = builtins.map ( roleModules = builtins.map (
role: role:
if builtins.elem role roles && clan-core.clanModules ? ${serviceName} then if builtins.elem role roles && inventory.modules ? ${serviceName} then
clan-core.clanModules.${serviceName} + "/roles/${role}.nix" inventory.modules.${serviceName} + "/roles/${role}.nix"
else else
throw "Module ${serviceName} doesn't have role: '${role}'. Role: ${ throw "Module ${serviceName} doesn't have role: '${role}'. Role: ${
clan-core.clanModules.${serviceName} inventory.modules.${serviceName}
}/roles/${role}.nix not found." }/roles/${role}.nix not found."
) machineRoles; ) machineRoles;
@@ -151,6 +152,7 @@ let
constraintAssertions = clan-core.lib.modules.checkConstraints { constraintAssertions = clan-core.lib.modules.checkConstraints {
moduleName = serviceName; moduleName = serviceName;
allModules = inventory.modules;
inherit resolvedRoles instanceName; inherit resolvedRoles instanceName;
}; };
in in

View File

@@ -92,6 +92,14 @@ in
./assertions.nix ./assertions.nix
]; ];
options = { options = {
modules = lib.mkOption {
type = types.attrsOf types.path;
internal = true;
visible = false;
default = { };
defaultText = "clanModules of clan-core";
};
assertions = lib.mkOption { assertions = lib.mkOption {
type = types.listOf types.unspecified; type = types.listOf types.unspecified;
internal = true; internal = true;