Merge pull request 'Reapply '(#3259) chore(buildClan): move machineClass option into inventory.machines submodule'' (#3268) from hsjobeki/clan-core:lib-cleanup into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3268
This commit is contained in:
hsjobeki
2025-04-09 16:50:15 +00:00
7 changed files with 85 additions and 32 deletions

View File

@@ -5,6 +5,9 @@
"description": "A nice thing",
"icon": "./path/to/icon.png",
"tags": ["1", "2", "3"]
},
"test-darwin-machine": {
"machineClass": "darwin"
}
},
"services": {

View File

@@ -162,16 +162,18 @@ let
};
};
allMachines = inventory.machines or { } // machines;
allMachines = inventoryClass.machines;
machineClass = lib.mapAttrs (name: _: inventory.machineClass.${name} or "nixos") allMachines;
configurations = lib.mapAttrs (
name: _: moduleSystemConstructor.${machineClass.${name}} { inherit name; }
machineClasses = lib.mapAttrs (
name: _: inventory.machines.${name}.machineClass or "nixos"
) allMachines;
nixosConfigurations = lib.filterAttrs (name: _: machineClass.${name} == "nixos") configurations;
darwinConfigurations = lib.filterAttrs (name: _: machineClass.${name} == "darwin") configurations;
configurations = lib.mapAttrs (
name: _: moduleSystemConstructor.${machineClasses.${name}} { inherit name; }
) allMachines;
nixosConfigurations = lib.filterAttrs (name: _: machineClasses.${name} == "nixos") configurations;
darwinConfigurations = lib.filterAttrs (name: _: machineClasses.${name} == "darwin") configurations;
# This instantiates NixOS for each system that we support:
# configPerSystem = <system>.<machine>.nixosConfiguration
@@ -182,7 +184,7 @@ let
lib.nameValuePair system (
lib.mapAttrs (
name: _:
moduleSystemConstructor.${machineClass.${name}} {
moduleSystemConstructor.${machineClasses.${name}} {
inherit name system;
pkgs = pkgsFor.${system};
}
@@ -197,7 +199,7 @@ let
lib.nameValuePair system (
lib.mapAttrs (
name: _: args:
moduleSystemConstructor.${machineClass.${name}} (
moduleSystemConstructor.${machineClasses.${name}} (
args
// {
inherit name system;

View File

@@ -210,14 +210,16 @@ in
meta.name = "test";
machines.machine1 = { };
machines.machine2 = { };
machines.machine3 = { };
inventory.machineClass.machine2 = "darwin";
inventory.machineClass.machine3 = "nixos";
inventory.machines.machine2 = {
machineClass = "darwin";
};
inventory.machines.machine3 = {
machineClass = "nixos";
};
};
in
{
inherit result;
expr = {
nixos = builtins.attrNames result.nixosConfigurations;
darwin = builtins.attrNames result.darwinConfigurations;
@@ -241,7 +243,6 @@ in
meta.name = "test";
machines.machine1.non_existent_option = throw "eval error";
inventory.machines.machine1.other_non_existent_option = throw "different eval error";
};
in
{

View File

@@ -243,6 +243,19 @@ in
options = {
inherit (metaOptionsWith name) name description icon;
machineClass = lib.mkOption {
default = "nixos";
type = types.enum [
"nixos"
"darwin"
];
description = ''
The module system that should be used to construct the machine
Set this to `darwin` for macOS machines
'';
};
tags = lib.mkOption {
description = ''
List of tags for the machine.
@@ -278,21 +291,6 @@ in
);
};
machineClass = lib.mkOption {
default = { };
type = types.attrsOf (
types.enum [
"nixos"
"darwin"
]
);
description = ''
The module system that should be used to construct the machine
Set this to `darwin` for macOS machines
'';
};
instances = lib.mkOption {
# Keep as internal until all de-/serialization issues are resolved
visible = false;
@@ -366,6 +364,7 @@ in
else
lib.warn "Inventory.instances and related features are still under development. Please use with care." v;
};
services = lib.mkOption {
description = ''
Services of the inventory.

View File

@@ -16,6 +16,7 @@ class Machine(TypedDict):
deploy: NotRequired[MachineDeploy]
description: NotRequired[str]
icon: NotRequired[str]
machineClass: NotRequired[Literal["nixos", "darwin"]]
name: NotRequired[str]
tags: NotRequired[list[str]]
@@ -29,7 +30,6 @@ Service = dict[str, Any]
class Inventory(TypedDict):
machineClass: NotRequired[dict[str, Any]]
machines: NotRequired[dict[str, Machine]]
meta: NotRequired[Meta]
modules: NotRequired[dict[str, Any]]

View File

@@ -62,7 +62,7 @@ class Machine:
def _class_(self) -> str:
try:
return self.flake.select(
f"clanInternals.inventory.machineClass.{self.name}"
f"clanInternals.inventory.machines.{self.name}.machineClass"
)
except ClanCmdError as e:
if re.search(f"error: attribute '{self.name}' missing", e.cmd.stderr):

View File

@@ -0,0 +1,48 @@
import pytest
from clan_cli.flake import Flake
from clan_cli.machines.machines import Machine
# Functions to test
from clan_cli.tests.fixtures_flakes import FlakeForTest
@pytest.mark.parametrize(
"test_flake_with_core",
[
# Two nixos machines
{
"inventory_expr": r"""{
machines.jon1 = { };
machines.jon2 = { machineClass = "nixos"; };
machines.sara = { machineClass = "darwin"; };
}"""
},
],
# Important!
# tells pytest to pass these values to the fixture
# So we can write it to the flake fixtures
indirect=True,
)
@pytest.mark.with_core
def test_inventory_deserialize_variants(
test_flake_with_core: FlakeForTest,
) -> None:
"""
Testing different inventory deserializations
Inventory should always be deserializable to a dict
"""
machine_jon1 = Machine(
name="jon",
flake=Flake(str(test_flake_with_core.path)),
)
machine_jon2 = Machine(
name="jon2",
flake=Flake(str(test_flake_with_core.path)),
)
machine_sara = Machine(
name="sara",
flake=Flake(str(test_flake_with_core.path)),
)
assert machine_jon1._class_ == "nixos"
assert machine_jon2._class_ == "nixos"
assert machine_sara._class_ == "darwin"