Refactor(build-inventory): remove build-inventory in favor of simple and expressive evalModules

This commit is contained in:
Johannes Kirschbauer
2025-06-26 09:46:26 +02:00
parent 8b2c6fc316
commit d9da723d5d
8 changed files with 64 additions and 105 deletions

View File

@@ -1,8 +1,4 @@
{ clanLib }:
{ {
_module.args = {
inherit clanLib;
};
imports = [ imports = [
./module.nix ./module.nix
./interface.nix ./interface.nix

View File

@@ -8,8 +8,11 @@
}: }:
{ {
flakePartsModule = { flakePartsModule = {
_module.args = {
inherit clanLib;
};
imports = [ imports = [
(lib.modules.importApply ./clan/default.nix { inherit clanLib; }) ./clan/default.nix
]; ];
}; };

View File

@@ -5,9 +5,11 @@
}: }:
let let
eval = lib.evalModules { eval = lib.evalModules {
# TODO: Move this into a 'classForMachines' or something
# @enzime why do we need this here?
class = "nixos"; class = "nixos";
modules = [ modules = [
(import ./clan/default.nix { inherit clanLib; }) clanLib.buildClanModule.flakePartsModule
]; ];
}; };
evalDocs = pkgs.nixosOptionsDoc { evalDocs = pkgs.nixosOptionsDoc {

View File

@@ -10,6 +10,7 @@
module: module:
(lib.evalModules { (lib.evalModules {
specialArgs = { specialArgs = {
inherit (clan-core) clanLib;
inherit inherit
self self
clan-core clan-core
@@ -18,7 +19,7 @@ module:
; ;
}; };
modules = [ modules = [
(import ./clan/default.nix { inherit (clan-core) clanLib; }) ./clan/default.nix
module module
{ {
inherit specialArgs; inherit specialArgs;

View File

@@ -4,7 +4,6 @@ let
in in
{ {
inherit (services) evalClanService mapInstances resolveModule; inherit (services) evalClanService mapInstances resolveModule;
inherit (import ../inventoryClass { inherit lib clanLib; }) buildInventory;
interface = { interface = {
_file = "clanLib.inventory.interface"; _file = "clanLib.inventory.interface";
imports = [ imports = [

View File

@@ -57,6 +57,8 @@ in
legacyPackages.evalTests-inventory = import ./tests { legacyPackages.evalTests-inventory = import ./tests {
inherit lib; inherit lib;
clan-core = self; clan-core = self;
inherit (self) clanLib;
inherit (self.inputs) nix-darwin;
}; };
checks = { checks = {

View File

@@ -1,18 +1,28 @@
{ clan-core, lib, ... }: {
clan-core,
nix-darwin,
lib,
clanLib,
}:
let let
inventory = ( # TODO: Unify these tests with clan tests
import ../../inventoryClass/default.nix { clan =
inherit lib; m:
clanLib = clan-core.clanLib; lib.evalModules {
} specialArgs = { inherit clan-core nix-darwin clanLib; };
); modules = [
inherit (inventory) buildInventory; ../../clan/default.nix
{
self = { };
}
m
];
};
in in
{ {
test_inventory_a = test_inventory_a =
let let
compiled = buildInventory { eval = clan {
flakeInputs = { };
inventory = { inventory = {
machines = { machines = {
A = { }; A = { };
@@ -28,10 +38,11 @@ in
}; };
in in
{ {
inherit eval;
expr = { expr = {
legacyModule = lib.filterAttrs ( legacyModule = lib.filterAttrs (
name: _: name == "isClanModule" name: _: name == "isClanModule"
) compiled.machines.A.compiledServices.legacyModule; ) eval.config.clanInternals.inventoryClass.machines.A.compiledServices.legacyModule;
}; };
expected = { expected = {
legacyModule = { legacyModule = {
@@ -41,24 +52,21 @@ in
test_inventory_empty = test_inventory_empty =
let let
compiled = buildInventory { eval = clan {
flakeInputs = { };
inventory = { }; inventory = { };
directory = ./.; directory = ./.;
}; };
in in
{ {
# Empty inventory should return an empty module # Empty inventory should return an empty module
expr = compiled.machines; expr = eval.config.clanInternals.inventoryClass.machines;
expected = { }; expected = { };
}; };
test_inventory_role_resolve = test_inventory_role_resolve =
let let
compiled = buildInventory { eval = clan {
flakeInputs = { };
directory = ./.; directory = ./.;
inventory = { inventory = {
modules = clan-core.clanModules;
services = { services = {
borgbackup.instance_1 = { borgbackup.instance_1 = {
roles.server.machines = [ "backup_server" ]; roles.server.machines = [ "backup_server" ];
@@ -78,10 +86,17 @@ in
in in
{ {
expr = { expr = {
m1 = (compiled.machines."backup_server").compiledServices.borgbackup.matchedRoles; m1 =
m2 = (compiled.machines."client_1_machine").compiledServices.borgbackup.matchedRoles; (eval.config.clanInternals.inventoryClass.machines."backup_server")
m3 = (compiled.machines."client_2_machine").compiledServices.borgbackup.matchedRoles; .compiledServices.borgbackup.matchedRoles;
inherit ((compiled.machines."client_2_machine").compiledServices.borgbackup) m2 =
(eval.config.clanInternals.inventoryClass.machines."client_1_machine")
.compiledServices.borgbackup.matchedRoles;
m3 =
(eval.config.clanInternals.inventoryClass.machines."client_2_machine")
.compiledServices.borgbackup.matchedRoles;
inherit
((eval.config.clanInternals.inventoryClass.machines."client_2_machine").compiledServices.borgbackup)
resolvedRolesPerInstance resolvedRolesPerInstance
; ;
}; };
@@ -113,11 +128,9 @@ in
}; };
test_inventory_tag_resolve = test_inventory_tag_resolve =
let let
configs = buildInventory { eval = clan {
flakeInputs = { };
directory = ./.; directory = ./.;
inventory = { inventory = {
modules = clan-core.clanModules;
services = { services = {
borgbackup.instance_1 = { borgbackup.instance_1 = {
roles.client.tags = [ "backup" ]; roles.client.tags = [ "backup" ];
@@ -136,7 +149,8 @@ in
}; };
in in
{ {
expr = configs.machines.client_1_machine.compiledServices.borgbackup.resolvedRolesPerInstance; expr =
eval.config.clanInternals.inventoryClass.machines.client_1_machine.compiledServices.borgbackup.resolvedRolesPerInstance;
expected = { expected = {
instance_1 = { instance_1 = {
client = { client = {
@@ -154,11 +168,9 @@ in
test_inventory_multiple_roles = test_inventory_multiple_roles =
let let
configs = buildInventory { eval = clan {
flakeInputs = { };
directory = ./.; directory = ./.;
inventory = { inventory = {
modules = clan-core.clanModules;
services = { services = {
borgbackup.instance_1 = { borgbackup.instance_1 = {
roles.client.machines = [ "machine_1" ]; roles.client.machines = [ "machine_1" ];
@@ -172,7 +184,8 @@ in
}; };
in in
{ {
expr = configs.machines.machine_1.compiledServices.borgbackup.matchedRoles; expr =
eval.config.clanInternals.inventoryClass.machines.machine_1.compiledServices.borgbackup.matchedRoles;
expected = [ expected = [
"client" "client"
"server" "server"
@@ -181,11 +194,9 @@ in
test_inventory_module_doesnt_exist = test_inventory_module_doesnt_exist =
let let
configs = buildInventory { eval = clan {
flakeInputs = { };
directory = ./.; directory = ./.;
inventory = { inventory = {
modules = clan-core.clanModules;
services = { services = {
fanatasy.instance_1 = { fanatasy.instance_1 = {
roles.default.machines = [ "machine_1" ]; roles.default.machines = [ "machine_1" ];
@@ -198,8 +209,8 @@ in
}; };
in in
{ {
inherit configs; inherit eval;
expr = configs.machines.machine_1.machineImports; expr = eval.config.clanInternals.inventoryClass.machines.machine_1.machineImports;
expectedError = { expectedError = {
type = "ThrownError"; type = "ThrownError";
msg = "ClanModule not found*"; msg = "ClanModule not found*";
@@ -208,11 +219,9 @@ in
test_inventory_role_doesnt_exist = test_inventory_role_doesnt_exist =
let let
configs = buildInventory { eval = clan {
flakeInputs = { };
directory = ./.; directory = ./.;
inventory = { inventory = {
modules = clan-core.clanModules;
services = { services = {
borgbackup.instance_1 = { borgbackup.instance_1 = {
roles.roleXYZ.machines = [ "machine_1" ]; roles.roleXYZ.machines = [ "machine_1" ];
@@ -225,8 +234,8 @@ in
}; };
in in
{ {
inherit configs; inherit eval;
expr = configs.machines.machine_1.machineImports; expr = eval.config.clanInternals.inventoryClass.machines.machine_1.machineImports;
expectedError = { expectedError = {
type = "ThrownError"; type = "ThrownError";
msg = ''Roles \["roleXYZ"\] are not defined in the service borgbackup''; msg = ''Roles \["roleXYZ"\] are not defined in the service borgbackup'';
@@ -236,11 +245,9 @@ in
# So the lib.warn is turned into abort # So the lib.warn is turned into abort
test_inventory_tag_doesnt_exist = test_inventory_tag_doesnt_exist =
let let
configs = buildInventory { eval = clan {
flakeInputs = { };
directory = ./.; directory = ./.;
inventory = { inventory = {
modules = clan-core.clanModules;
services = { services = {
borgbackup.instance_1 = { borgbackup.instance_1 = {
roles.client.machines = [ "machine_1" ]; roles.client.machines = [ "machine_1" ];
@@ -256,7 +263,7 @@ in
}; };
in in
{ {
expr = configs.machines.machine_1.machineImports; expr = eval.config.clanInternals.inventoryClass.machines.machine_1.machineImports;
expectedError = { expectedError = {
type = "Error"; type = "Error";
# TODO: Add warning matching in nix-unit # TODO: Add warning matching in nix-unit
@@ -265,11 +272,9 @@ in
}; };
test_inventory_disabled_service = test_inventory_disabled_service =
let let
configs = buildInventory { eval = clan {
flakeInputs = { };
directory = ./.; directory = ./.;
inventory = { inventory = {
modules = clan-core.clanModules;
services = { services = {
borgbackup.instance_1 = { borgbackup.instance_1 = {
enabled = false; enabled = false;
@@ -285,10 +290,10 @@ in
}; };
in in
{ {
inherit configs; inherit eval;
expr = builtins.filter ( expr = builtins.filter (
v: v != { } && !v.clan.inventory.assertions ? "alive.assertion.inventory" v: v != { } && !v.clan.inventory.assertions ? "alive.assertion.inventory"
) configs.machines.machine_1.machineImports; ) eval.config.clanInternals.inventoryClass.machines.machine_1.machineImports;
expected = [ ]; expected = [ ];
}; };
} }

View File

@@ -1,49 +0,0 @@
# Generate partial NixOS configurations for every machine in the inventory
# This function is responsible for generating the module configuration for every machine in the inventory.
{ lib, clanLib }:
let
/*
Returns a set with NixOS configuration for every machine in the inventory.
machinesFromInventory :: Inventory -> { ${machine_name} :: NixOSConfiguration }
*/
buildInventory =
{
inventory,
directory,
flakeInputs,
prefix ? [ ],
localModuleSet ? { },
}:
(lib.evalModules {
# TODO: move clanLib from specialArgs to options
specialArgs = {
inherit clanLib;
};
modules = [
./builder/default.nix
(lib.modules.importApply ./service-list-from-inputs.nix {
inherit flakeInputs clanLib localModuleSet;
})
{ inherit directory inventory; }
(
# config.distributedServices.allMachines.${name} or [ ];
{ config, ... }:
{
distributedServices = clanLib.inventory.mapInstances {
inherit (config) inventory;
inherit localModuleSet;
inherit flakeInputs;
prefix = prefix ++ [ "distributedServices" ];
};
machines = config.distributedServices.allMachines;
}
)
./inventory-introspection.nix
];
}).config;
in
{
inherit buildInventory;
}