buildClan function: export all machines via nixosModules/darwinModules

We want each machine not only to be exposed via nixosConfigurations but also as a module.
This allows re-importing the machine in tests and override the architecture for example.
This commit is contained in:
DavHau
2025-06-09 18:00:28 +07:00
parent baeefc8ba1
commit d37c7c4c05
12 changed files with 100 additions and 25 deletions

View File

@@ -100,7 +100,7 @@ are loaded when using Clan:
}; };
in in
{ {
inherit (clan) nixosConfigurations clanInternals; inherit (clan) nixosConfigurations nixosModules clanInternals;
# elided for brevity # elided for brevity
}; };

View File

@@ -162,6 +162,32 @@ in
default = { }; default = { };
}; };
nixosModules = lib.mkOption {
# Hide from documentation.
# Exposed at the top-level of the flake, clan.nixosModules should not used by the user.
# Instead, the user should use the `.#nixosModules` attribute of the flake output.
visible = false;
type = types.lazyAttrsOf types.raw;
default = { };
description = ''
NixOS modules that are generated by clan.
These are used to generate the `nixosConfigurations`.
'';
};
darwinModules = lib.mkOption {
# Hide from documentation.
# Exposed at the top-level of the flake, clan.darwinModules should not used by the user.
# Instead, the user should use the `.#darwinModules` attribute of the flake output.
visible = false;
type = types.lazyAttrsOf types.raw;
default = { };
description = ''
Darwin modules that are generated by clan.
These are used to generate the `darwinConfigurations`.
'';
};
# flake.clanInternals # flake.clanInternals
clanInternals = lib.mkOption { clanInternals = lib.mkOption {
# Hide from documentation. Exposes internals to the cli. # Hide from documentation. Exposes internals to the cli.

View File

@@ -26,7 +26,4 @@
inherit name; inherit name;
}; };
}; };
# TODO: move into nixosModules
networking.hostName = lib.mkDefault name;
} }

View File

@@ -7,11 +7,16 @@
... ...
}: }:
let let
inherit (lib)
flip
mapAttrs'
;
inherit (config) inherit (config)
directory directory
inventory
pkgsForSystem pkgsForSystem
specialArgs specialArgs
inventory
; ;
inherit (clan-core.clanLib.inventory) buildInventory; inherit (clan-core.clanLib.inventory) buildInventory;
@@ -75,6 +80,31 @@ let
} }
) allMachines; ) allMachines;
# Expose reusable modules these can be imported or wrapped or instantiated
# - by the user
# - by some test frameworks
# IMPORTANT!: It is utterly important that we don't add any logic outside of these modules, as it would get tested.
nixosModules' = lib.filterAttrs (
name: _: inventory.machines.${name}.machineClass or "nixos" == "nixos"
) (config.outputs.moduleForMachine);
darwinModules' = lib.filterAttrs (
name: _: inventory.machines.${name}.machineClass or "nixos" == "darwin"
) (config.outputs.moduleForMachine);
nixosModules = flip mapAttrs' nixosModules' (
name: machineModule: {
name = "clan-machine-${name}";
value = machineModule;
}
);
darwinModules = flip mapAttrs' darwinModules' (
name: machineModule: {
name = "clan-machine-${name}";
value = machineModule;
}
);
nixosConfigurations = lib.filterAttrs (name: _: machineClasses.${name} == "nixos") configurations; nixosConfigurations = lib.filterAttrs (name: _: machineClasses.${name} == "nixos") configurations;
darwinConfigurations = lib.filterAttrs (name: _: machineClasses.${name} == "darwin") configurations; darwinConfigurations = lib.filterAttrs (name: _: machineClasses.${name} == "darwin") configurations;
@@ -180,6 +210,9 @@ in
# - darwinModules (_class = darwin) # - darwinModules (_class = darwin)
(lib.optionalAttrs (clan-core ? "${_class}Modules") clan-core."${_class}Modules".clanCore) (lib.optionalAttrs (clan-core ? "${_class}Modules") clan-core."${_class}Modules".clanCore)
] ++ lib.optionals (_class == "nixos") (v.machineImports or [ ]); ] ++ lib.optionals (_class == "nixos") (v.machineImports or [ ]);
# default hostname
networking.hostName = lib.mkDefault name;
} }
) )
) inventoryClass.machines) ) inventoryClass.machines)
@@ -193,6 +226,10 @@ in
self = lib.mkDefault config.self; self = lib.mkDefault config.self;
}; };
# expose all machines as modules for re-use
inherit nixosModules;
inherit darwinModules;
# Ready to use configurations # Ready to use configurations
# These are only shallow wrapping the 'nixosModules' or 'darwinModules' with # These are only shallow wrapping the 'nixosModules' or 'darwinModules' with
# lib.nixosSystem # lib.nixosSystem
@@ -200,17 +237,6 @@ in
inherit darwinConfigurations; inherit darwinConfigurations;
clanInternals = { clanInternals = {
# Expose reusable modules these can be imported or wrapped or instantiated
# - by the user
# - by some test frameworks
# IMPORTANT!: It is utterly important that we don't add any logic outside of these modules, as it would get tested.
nixosModules = lib.filterAttrs (
name: _: inventory.machines.${name}.machineClass or "nixos" == "nixos"
) (config.outputs.moduleForMachine);
darwinModules = lib.filterAttrs (
name: _: inventory.machines.${name}.machineClass or "nixos" == "darwin"
) (config.outputs.moduleForMachine);
inherit inventoryClass; inherit inventoryClass;
# Endpoint that can be called to get a service schema # Endpoint that can be called to get a service schema

View File

@@ -14,6 +14,8 @@
topLevel = [ topLevel = [
"clanInternals" "clanInternals"
"nixosConfigurations" "nixosConfigurations"
"nixosModules"
"darwinConfigurations" "darwinConfigurations"
"darwinModules"
]; ];
} }

View File

@@ -157,6 +157,24 @@ in
]; ];
}; };
test_machines_are_modules =
let
result = buildClan {
self = {
inputs = { };
};
directory = ../../.;
meta.name = "test-clan-core";
};
in
{
expr = builtins.attrNames result.nixosModules;
expected = [
"clan-machine-test-backup"
"clan-machine-test-inventory-machine"
];
};
test_buildClan_all_machines = test_buildClan_all_machines =
let let
result = buildClan { result = buildClan {

View File

@@ -6,13 +6,14 @@
}: }:
let let
inherit (lib) inherit (lib)
flatten
flip
mapAttrs'
mapAttrsToList
mkOption mkOption
removePrefix removePrefix
types types
mapAttrsToList
flip
unique unique
flatten
; ;
clanLib = config.flake.clanLib; clanLib = config.flake.clanLib;
@@ -143,7 +144,12 @@ in
# Inherit all nodes from the clan # Inherit all nodes from the clan
# i.e. nodes.jon <- clan.machines.jon # i.e. nodes.jon <- clan.machines.jon
# clanInternals.nixosModules contains nixosModules per node # clanInternals.nixosModules contains nixosModules per node
nodes = clanFlakeResult.clanInternals.nixosModules; nodes = flip mapAttrs' clanFlakeResult.nixosModules (
name: machineModule: {
name = removePrefix "clan-machine-" name;
value = machineModule;
}
);
# !WARNING: Write a detailed comment if adding new options here # !WARNING: Write a detailed comment if adding new options here
# We should be very careful about adding new options here because it affects all tests # We should be very careful about adding new options here because it affects all tests

View File

@@ -62,6 +62,6 @@
in in
{ {
clan = clan_attrs_json; clan = clan_attrs_json;
inherit (clan) nixosConfigurations clanInternals; inherit (clan) nixosConfigurations nixosModules clanInternals;
}; };
} }

View File

@@ -44,6 +44,6 @@
}; };
in in
{ {
inherit (clan) nixosConfigurations clanInternals; inherit (clan) nixosConfigurations nixosModules clanInternals;
}; };
} }

View File

@@ -19,6 +19,6 @@
}; };
in in
{ {
inherit (clan) nixosConfigurations clanInternals; inherit (clan) nixosConfigurations nixosModules clanInternals;
}; };
} }

View File

@@ -10,6 +10,6 @@
in in
{ {
# all machines managed by Clan # all machines managed by Clan
inherit (clan) nixosConfigurations clanInternals; inherit (clan) nixosConfigurations nixosModules clanInternals;
}; };
} }

View File

@@ -26,7 +26,7 @@
}; };
in in
{ {
inherit (clan) nixosConfigurations clanInternals; inherit (clan) nixosConfigurations nixosModules clanInternals;
# Add the Clan cli tool to the dev shell. # Add the Clan cli tool to the dev shell.
# Use "nix develop" to enter the dev shell. # Use "nix develop" to enter the dev shell.
devShells = devShells =