build-inventory: move inventory and inventoryClass into explizitly different folders

This commit is contained in:
Johannes Kirschbauer
2025-06-25 17:45:10 +02:00
parent ae4e18c152
commit 345aa12e99
42 changed files with 49 additions and 139 deletions

View File

@@ -30,7 +30,7 @@
{ {
imports = [ imports = [
serviceModule serviceModule
../../../lib/inventory/distributed-service/service-module.nix ../../../lib/modules/inventory/distributed-service/service-module.nix
]; ];
} }
]; ];
@@ -124,7 +124,7 @@
_file = "docs flake-module"; _file = "docs flake-module";
imports = [ imports = [
{ _module.args = { inherit clanLib; }; } { _module.args = { inherit clanLib; }; }
(import ../../../lib/inventory/build-inventory/roles-interface.nix { (import ../../../lib/modules/inventoryClass/roles-interface.nix {
nestedSettingsOption = mkOption { nestedSettingsOption = mkOption {
type = types.raw; type = types.raw;
description = '' description = ''
@@ -154,7 +154,7 @@
_file = "docs mkScope"; _file = "docs mkScope";
} }
{ noInstanceOptions = true; } { noInstanceOptions = true; }
../../../lib/inventory/build-inventory/interface.nix ../../../lib/modules/inventoryClass/interface.nix
] ++ mapAttrsToList fakeInstanceOptions modules; ] ++ mapAttrsToList fakeInstanceOptions modules;
urlPrefix = "https://github.com/nix-community/dream2nix/blob/main/"; urlPrefix = "https://github.com/nix-community/dream2nix/blob/main/";
}; };

View File

@@ -38,10 +38,10 @@ lib.fix (clanLib: {
}).config.result.api.schema; }).config.result.api.schema;
# ------------------------------------ # ------------------------------------
# ClanLib functions # ClanLib functions
evalClan = clanLib.callLib ./inventory/eval-clan-modules { }; evalClan = clanLib.callLib ./modules/inventory/eval-clan-modules { };
buildClanModule = clanLib.callLib ./modules { }; buildClanModule = clanLib.callLib ./modules { };
inventory = clanLib.callLib ./inventory { }; inventory = clanLib.callLib ./modules/inventory { };
modules = clanLib.callLib ./inventory/frontmatter { }; modules = clanLib.callLib ./modules/inventory/frontmatter { };
test = clanLib.callLib ./test { }; test = clanLib.callLib ./test { };
# Custom types # Custom types
types = clanLib.callLib ./types { }; types = clanLib.callLib ./types { };

View File

@@ -10,7 +10,7 @@ rec {
./modules/flake-module.nix ./modules/flake-module.nix
./clanTest/flake-module.nix ./clanTest/flake-module.nix
./introspection/flake-module.nix ./introspection/flake-module.nix
./inventory/flake-module.nix ./modules/inventory/flake-module.nix
./jsonschema/flake-module.nix ./jsonschema/flake-module.nix
./types/flake-module.nix ./types/flake-module.nix
]; ];

View File

@@ -1,90 +0,0 @@
# Inventory
The inventory is our concept for distributed services. Users can configure multiple machines with minimal effort.
- The inventory acts as a declarative source of truth for all machine configurations.
- Users can easily add or remove machines to/from services.
- Ensures that all machines and services are configured consistently, across multiple nixosConfigs.
- Defaults and predefined roles in our modules minimizes the need for manual configuration.
Open questions:
- [ ] How do we set default role, description and other metadata?
- It must be accessible from Python.
- It must set the value in the module system.
- [ ] Inventory might use assertions. Should each machine inherit the inventory assertions ?
- [ ] Is the service config interface the same as the module config interface ?
- [ ] As a user do I want to see borgbackup as the high level category?
Architecture
```
nixosConfig < machine_module < inventory
---------------------------------------------
nixos < borgbackup <- inventory <-> UI
creates the config Maps from high level services to the borgbackup clan module
for ONE machine Inventory is completely serializable.
UI can interact with the inventory to define machines, and services
Defining Users is out of scope for the first prototype.
```
## Provides a specification for the inventory
It is used for design phase and as validation helper.
> Cue is less verbose and easier to understand and maintain than json-schema.
> Json-schema, if needed can be easily generated on-the fly.
## Checking validity
Directly check a json against the schema
`cue vet inventory.json root.cue -d '#Root'`
## Json schema
Export the json-schema i.e. for usage in python / javascript / nix
`cue export --out openapi root.cue`
## Usage
Comments are rendered as descriptions in the json schema.
```cue
// A name of the clan (primarily shown by the UI)
name: string
```
Cue open sets. In the following `foo = {...}` means that the key `foo` can contain any arbitrary json object.
```cue
foo: { ... }
```
Cue dynamic keys.
```cue
[string]: {
attr: string
}
```
This is the schema of
```json
{
"a": {
"attr": "foo"
},
"b": {
"attr": "bar"
}
// ... Indefinitely more dynamic keys of type "string"
}
```

View File

@@ -9,7 +9,7 @@
{ machines, ... }: { machines, ... }:
{ {
# Only compute the default value # Only compute the default value
# The option MUST be defined in ./build-inventory/interface.nix # The option MUST be defined in inventoryClass/interface.nix
all = lib.mkDefault (builtins.attrNames machines); all = lib.mkDefault (builtins.attrNames machines);
nixos = lib.mkDefault ( nixos = lib.mkDefault (
builtins.attrNames (lib.filterAttrs (_n: m: m.machineClass == "nixos") machines) builtins.attrNames (lib.filterAttrs (_n: m: m.machineClass == "nixos") machines)

View File

@@ -104,7 +104,7 @@ in
_module.args = { inherit clanLib; }; _module.args = { inherit clanLib; };
_file = "clan interface"; _file = "clan interface";
} }
../../inventory/build-inventory/interface.nix ../inventoryClass/interface.nix
]; ];
}; };
description = '' description = ''
@@ -120,7 +120,7 @@ in
Global information about the clan. Global information about the clan.
''; '';
type = types.deferredModuleWith { type = types.deferredModuleWith {
staticModules = [ ../../inventory/build-inventory/meta-interface.nix ]; staticModules = [ ../inventoryClass/meta-interface.nix ];
}; };
default = { }; default = { };
}; };

View File

@@ -42,38 +42,6 @@ let
); );
inherit (clan-core) clanLib; inherit (clan-core) clanLib;
inventoryClass =
let
localModuleSet =
lib.filterAttrs (n: _: !inventory._legacyModules ? ${n}) inventory.modules // config.modules;
flakeInputs = config.self.inputs;
in
{
_module.args = {
inherit clanLib;
};
imports = [
../../inventory/build-inventory/builder/default.nix
(lib.modules.importApply ../../inventory/build-inventory/service-list-from-inputs.nix {
inherit localModuleSet flakeInputs clanLib;
})
{
inherit inventory directory;
}
(
{ config, ... }:
{
distributedServices = clanLib.inventory.mapInstances {
inherit (config) inventory;
inherit localModuleSet flakeInputs;
prefix = [ "distributedServices" ];
};
machines = config.distributedServices.allMachines;
}
)
../../inventory/build-inventory/inventory-introspection.nix
];
};
moduleSystemConstructor = { moduleSystemConstructor = {
# TODO: remove default system once we have a hardware-config mechanism # TODO: remove default system once we have a hardware-config mechanism
@@ -81,7 +49,7 @@ let
darwin = nix-darwin.lib.darwinSystem; darwin = nix-darwin.lib.darwinSystem;
}; };
allMachines = inventoryClass.machines; # <- inventory.machines <- clan.machines allMachines = config.clanInternals.inventoryClass.machines; # <- inventory.machines <- clan.machines
machineClasses = lib.mapAttrs ( machineClasses = lib.mapAttrs (
name: _: inventory.machines.${name}.machineClass or "nixos" name: _: inventory.machines.${name}.machineClass or "nixos"
@@ -238,7 +206,7 @@ in
networking.hostName = lib.mkDefault name; networking.hostName = lib.mkDefault name;
} }
) )
) inventoryClass.machines) ) config.clanInternals.inventoryClass.machines)
# The user can define some machine config here # The user can define some machine config here
# i.e. 'clan.machines.jon = ...' # i.e. 'clan.machines.jon = ...'
@@ -260,7 +228,39 @@ in
inherit darwinConfigurations; inherit darwinConfigurations;
clanInternals = { clanInternals = {
inherit inventoryClass; inventoryClass =
let
localModuleSet =
lib.filterAttrs (n: _: !inventory._legacyModules ? ${n}) inventory.modules // config.modules;
flakeInputs = config.self.inputs;
in
{
_module.args = {
inherit clanLib;
};
imports = [
../inventoryClass/builder/default.nix
(lib.modules.importApply ../inventoryClass/service-list-from-inputs.nix {
inherit localModuleSet flakeInputs clanLib;
})
{
inherit inventory directory;
}
(
{ config, ... }:
{
distributedServices = clanLib.inventory.mapInstances {
inherit (config) inventory;
inherit localModuleSet flakeInputs;
prefix = [ "distributedServices" ];
};
machines = config.distributedServices.allMachines;
}
)
../inventoryClass/inventory-introspection.nix
];
};
# TODO: remove this after a month or so # TODO: remove this after a month or so
# This is here for backwards compatibility for older CLI versions # This is here for backwards compatibility for older CLI versions
inventory = config.inventory; inventory = config.inventory;

View File

@@ -4,11 +4,11 @@ let
in in
{ {
inherit (services) evalClanService mapInstances resolveModule; inherit (services) evalClanService mapInstances resolveModule;
inherit (import ./build-inventory { inherit lib clanLib; }) buildInventory; inherit (import ../inventoryClass { inherit lib clanLib; }) buildInventory;
interface = { interface = {
_file = "inventory/default.nix"; _file = "clanLib.inventory.interface";
imports = [ imports = [
./build-inventory/interface.nix ../inventoryClass/interface.nix
]; ];
_module.args = { inherit clanLib; }; _module.args = { inherit clanLib; };
}; };

View File

@@ -19,7 +19,7 @@ let
frontMatterSchema = jsonLib.parseOptions self.clanLib.modules.frontmatterOptions { }; frontMatterSchema = jsonLib.parseOptions self.clanLib.modules.frontmatterOptions { };
inventorySchema = jsonLib.parseModule ({ inventorySchema = jsonLib.parseModule ({
imports = [ ../build-inventory/interface.nix ]; imports = [ ../../inventoryClass/interface.nix ];
_module.args = { inherit (self) clanLib; }; _module.args = { inherit (self) clanLib; };
}); });