Inventory: init external modules support
This commit is contained in:
committed by
hsjobeki
parent
604c16c30f
commit
25fb899f64
@@ -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; };
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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; };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user