Merge pull request 'API(cli): add method to Flake class to allow calling nix functions' (#3502) from hsjobeki/clan-core:improvements-2 into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3502
This commit is contained in:
hsjobeki
2025-05-05 20:16:28 +00:00
12 changed files with 185 additions and 56 deletions

View File

@@ -12,8 +12,10 @@ let
inventory,
directory,
flakeInputs,
prefix ? [ ],
}:
(lib.evalModules {
# TODO: remove clanLib from specialArgs
specialArgs = {
inherit clanLib;
};
@@ -24,13 +26,16 @@ let
# config.distributedServices.allMachines.${name} or [ ];
{ config, ... }:
{
distributedServices = clanLib.inventory.mapInstances {
inherit (config) inventory;
inherit flakeInputs;
prefix = prefix ++ [ "distributedServices" ];
};
machines = lib.mapAttrs (_machineName: v: {
machineImports = v;
}) config.distributedServices.allMachines;
}
)
(lib.modules.importApply ./inventory-introspection.nix { inherit clanLib; })

View File

@@ -3,7 +3,7 @@ let
services = clanLib.callLib ./distributed-service/inventory-adapter.nix { };
in
{
inherit (services) evalClanService mapInstances;
inherit (services) evalClanService mapInstances resolveModule;
inherit (import ./build-inventory { inherit lib clanLib; }) buildInventory;
interface = ./build-inventory/interface.nix;
# Returns the list of machine names

View File

@@ -1,7 +1,7 @@
# This module enables itself if
# manifest.features.API = true
# It converts the roles.interface to a json-schema
{ clanLib, attrName }:
{ clanLib, prefix }:
let
converter = clanLib.jsonschema {
includeDefaults = true;
@@ -45,7 +45,7 @@ in
To see the evaluation problem run
nix eval .#clanInternals.inventoryClass.distributedServices.importedModulesEvaluated.${attrName}.config.result.api.schema.${roleName}
nix eval .#${lib.concatStringsSep "." prefix}.config.result.api.schema.${roleName}
'';
assertion = (builtins.tryEval (lib.deepSeq config.result.api.schema.${roleName} true)).success;
};

View File

@@ -16,27 +16,72 @@
}:
let
evalClanService =
{ modules, key }:
{ modules, prefix }:
(lib.evalModules {
class = "clan.service";
modules = [
./service-module.nix
# feature modules
(lib.modules.importApply ./api-feature.nix {
inherit clanLib;
attrName = key;
inherit clanLib prefix;
})
] ++ modules;
});
resolveModule =
{
moduleSpec,
flakeInputs,
localModuleSet,
}:
let
# TODO:
resolvedModuleSet =
# If the module.name is self then take the modules defined in the flake
# Otherwise its an external input which provides the modules via 'clan.modules' attribute
if moduleSpec.input == null then
localModuleSet
else
let
input =
flakeInputs.${moduleSpec.input} or (throw ''
Flake doesn't provide input with name '${moduleSpec.input}'
Choose one of the following inputs:
- ${
builtins.concatStringsSep "\n- " (
lib.attrNames (lib.filterAttrs (_name: input: input ? clan) flakeInputs)
)
}
To import a local module from 'inventory.modules' remove the 'input' attribute from the module definition
Remove the following line from the module definition:
...
- module.input = "${moduleSpec.input}"
'');
clanAttrs =
input.clan
or (throw "It seems the flake input ${moduleSpec.input} doesn't export any clan resources");
in
clanAttrs.modules;
resolvedModule =
resolvedModuleSet.${moduleSpec.name}
or (throw "flake doesn't provide clan-module with name ${moduleSpec.name}");
in
resolvedModule;
in
{
inherit evalClanService;
inherit evalClanService resolveModule;
mapInstances =
{
# This is used to resolve the module imports from 'flake.inputs'
flakeInputs,
# The clan inventory
inventory,
prefix ? [ ],
}:
let
# machineHasTag = machineName: tagName: lib.elem tagName inventory.machines.${machineName}.tags;
@@ -45,42 +90,11 @@ in
importedModuleWithInstances = lib.mapAttrs (
instanceName: instance:
let
# TODO:
resolvedModuleSet =
# If the module.name is self then take the modules defined in the flake
# Otherwise its an external input which provides the modules via 'clan.modules' attribute
if instance.module.input == null then
inventory.modules
else
let
input =
flakeInputs.${instance.module.input} or (throw ''
Flake doesn't provide input with name '${instance.module.input}'
Choose one of the following inputs:
- ${
builtins.concatStringsSep "\n- " (
lib.attrNames (lib.filterAttrs (_name: input: input ? clan) flakeInputs)
)
}
To import a local module from 'inventory.modules' remove the 'input' attribute from the module definition
Remove the following line from the module definition:
...
- module.input = "${instance.module.input}"
'');
clanAttrs =
input.clan
or (throw "It seems the flake input ${instance.module.input} doesn't export any clan resources");
in
clanAttrs.modules;
resolvedModule =
resolvedModuleSet.${instance.module.name}
or (throw "flake doesn't provide clan-module with name ${instance.module.name}");
resolvedModule = resolveModule {
moduleSpec = instance.module;
localModuleSet = inventory.modules;
inherit flakeInputs;
};
# Every instance includes machines via roles
# :: { client :: ... }
@@ -138,7 +152,7 @@ in
importedModulesEvaluated = lib.mapAttrs (
module_ident: instances:
evalClanService {
key = module_ident;
prefix = prefix ++ [ module_ident ];
modules =
[
# Import the resolved module.