clan: Add autoloaded clanModules from flake inputs. Rename 'directory' to 'self' in buildClan

This commit is contained in:
Qubasa
2025-01-24 12:32:04 +07:00
parent 83c6ad19eb
commit ed6aaf5f0c
14 changed files with 70 additions and 33 deletions

View File

@@ -41,7 +41,7 @@
{ {
clan = { clan = {
meta.name = "clan-core"; meta.name = "clan-core";
directory = self; inherit self;
}; };
systems = import systems; systems = import systems;
imports = imports =

View File

@@ -0,0 +1,23 @@
{
lib,
self,
...
}:
let
# Returns an attrset with inputs that have the attribute `clanModules`
inputsWithClanModules = lib.filterAttrs (
_name: value: builtins.hasAttr "clanModules" value
) self.inputs;
flattenedClanModules = lib.foldl' (
acc: input:
lib.mkMerge [
acc
input.clanModules
]
) { } (lib.attrValues inputsWithClanModules);
in
{
inventory.modules = flattenedClanModules;
}

View File

@@ -8,7 +8,8 @@
}: }:
{ {
## Inputs ## Inputs
directory, # The directory containing the machines subdirectory # allows to include machine-specific modules i.e. machines.${name} = { ... } directory ? null, # The directory containing the machines subdirectory # allows to include machine-specific modules i.e. machines.${name} = { ... }
self ? null,
# A map from arch to pkgs, if specified this nixpkgs will be only imported once for each system. # A map from arch to pkgs, if specified this nixpkgs will be only imported once for each system.
# This improves performance, but all nipxkgs.* options will be ignored. # This improves performance, but all nipxkgs.* options will be ignored.
# deadnix: skip # deadnix: skip
@@ -19,15 +20,27 @@
... ...
}@attrs: }@attrs:
let let
eval = import ./eval.nix { evalUnchecked = import ./eval.nix {
inherit inherit
lib lib
nixpkgs nixpkgs
specialArgs
clan-core clan-core
; ;
self = directory; inherit specialArgs;
self = if self != null then self else directory;
}; };
# Doing `self ? lib.trace "please use self" directory`, doesn't work
# as when both (directory and self) are set we get an infinite recursion error
eval =
if directory == null && self == null then
throw "The buildClan function requires argument 'self' to be set"
else if directory != null && self != null then
throw "Both 'self' and 'directory' are set, please remove 'directory' in favor of the 'self' argument"
else if directory != null then
lib.warn "The 'directory' argument in buildClan has been deprecated in favor of the 'self' argument" evalUnchecked
else
evalUnchecked;
rest = builtins.removeAttrs attrs [ "specialArgs" ]; rest = builtins.removeAttrs attrs [ "specialArgs" ];
in in
eval { eval {
@@ -35,5 +48,6 @@ eval {
rest rest
# implementation # implementation
./module.nix ./module.nix
./auto-imports.nix
]; ];
} }

View File

@@ -8,8 +8,7 @@ let
in in
{ {
options = { options = {
# Required options self = lib.mkOption {
directory = lib.mkOption {
type = types.path; type = types.path;
default = self; default = self;
defaultText = "Root directory of the flake"; defaultText = "Root directory of the flake";

View File

@@ -7,7 +7,7 @@
}: }:
let let
inherit (config) inherit (config)
directory self
machines machines
pkgsForSystem pkgsForSystem
specialArgs specialArgs
@@ -44,7 +44,7 @@ let
serviceConfigs = ( serviceConfigs = (
buildInventory { buildInventory {
inherit inventory; inherit inventory;
inherit directory; inherit self;
} }
); );
@@ -59,14 +59,14 @@ let
nixpkgs.lib.nixosSystem { nixpkgs.lib.nixosSystem {
modules = modules =
let let
hwConfig = "${directory}/machines/${name}/hardware-configuration.nix"; hwConfig = "${self}/machines/${name}/hardware-configuration.nix";
diskoConfig = "${directory}/machines/${name}/disko.nix"; diskoConfig = "${self}/machines/${name}/disko.nix";
in in
[ [
{ {
# Autoinclude configuration.nix and hardware-configuration.nix # Autoinclude configuration.nix and hardware-configuration.nix
imports = builtins.filter builtins.pathExists [ imports = builtins.filter builtins.pathExists [
"${directory}/machines/${name}/configuration.nix" "${self}/machines/${name}/configuration.nix"
hwConfig hwConfig
diskoConfig diskoConfig
]; ];
@@ -81,7 +81,7 @@ let
{ {
# Settings # Settings
clan.core.settings = { clan.core.settings = {
inherit directory; directory = self;
inherit (config.inventory.meta) name icon; inherit (config.inventory.meta) name icon;
machine = { machine = {
@@ -160,7 +160,7 @@ let
) supportedSystems ) supportedSystems
); );
inventoryFile = "${directory}/inventory.json"; inventoryFile = "${self}/inventory.json";
inventoryLoaded = inventoryLoaded =
if builtins.pathExists inventoryFile then if builtins.pathExists inventoryFile then
@@ -171,6 +171,7 @@ let
in in
{ {
imports = [ imports = [
(lib.mkRenamedOptionModule [ "directory" ] [ "self" ])
# Merge the inventory file # Merge the inventory file
{ {
inventory = _: { inventory = _: {
@@ -180,9 +181,9 @@ in
} }
# TODO: Figure out why this causes infinite recursion # TODO: Figure out why this causes infinite recursion
{ {
inventory.machines = lib.optionalAttrs (builtins.pathExists "${directory}/machines") ( inventory.machines = lib.optionalAttrs (builtins.pathExists "${self}/machines") (
builtins.mapAttrs (_n: _v: { }) ( builtins.mapAttrs (_n: _v: { }) (
(lib.filterAttrs (_: t: t == "directory") (builtins.readDir "${directory}/machines")) (lib.filterAttrs (_: t: t == "directory") (builtins.readDir "${self}/machines"))
) )
); );
} }

View File

@@ -28,7 +28,7 @@ in
test_all_simple = test_all_simple =
let let
config = evalClan { config = evalClan {
directory = ./.; self = ./.;
machines = { }; machines = { };
inventory = { inventory = {
meta.name = "test"; meta.name = "test";

View File

@@ -197,7 +197,7 @@ let
machinesFromInventory :: Inventory -> { ${machine_name} :: NixOSConfiguration } machinesFromInventory :: Inventory -> { ${machine_name} :: NixOSConfiguration }
*/ */
buildInventory = buildInventory =
{ inventory, directory }: { inventory, self }:
# For every machine in the inventory, build a NixOS configuration # For every machine in the inventory, build a NixOS configuration
# For each machine generate config, forEach service, if the machine is used. # For each machine generate config, forEach service, if the machine is used.
builtins.mapAttrs ( builtins.mapAttrs (
@@ -207,8 +207,8 @@ let
machineName machineName
machineConfig machineConfig
inventory inventory
directory
; ;
directory = self;
} }
) (inventory.machines or { }); ) (inventory.machines or { });
in in

View File

@@ -13,14 +13,14 @@ in
# Empty inventory should return an empty module # Empty inventory should return an empty module
expr = buildInventory { expr = buildInventory {
inventory = { }; inventory = { };
directory = ./.; self = ./.;
}; };
expected = { }; expected = { };
}; };
test_inventory_role_imports = test_inventory_role_imports =
let let
configs = buildInventory { configs = buildInventory {
directory = ./.; self = ./.;
inventory = { inventory = {
modules = clan-core.clanModules; modules = clan-core.clanModules;
services = { services = {
@@ -62,7 +62,7 @@ in
test_inventory_tag_resolve = test_inventory_tag_resolve =
let let
configs = buildInventory { configs = buildInventory {
directory = ./.; self = ./.;
inventory = { inventory = {
modules = clan-core.clanModules; modules = clan-core.clanModules;
services = { services = {
@@ -102,7 +102,7 @@ in
test_inventory_multiple_roles = test_inventory_multiple_roles =
let let
configs = buildInventory { configs = buildInventory {
directory = ./.; self = ./.;
inventory = { inventory = {
modules = clan-core.clanModules; modules = clan-core.clanModules;
services = { services = {
@@ -132,7 +132,7 @@ in
test_inventory_module_doesnt_exist = test_inventory_module_doesnt_exist =
let let
configs = buildInventory { configs = buildInventory {
directory = ./.; self = ./.;
inventory = { inventory = {
modules = clan-core.clanModules; modules = clan-core.clanModules;
services = { services = {
@@ -157,7 +157,7 @@ in
test_inventory_role_doesnt_exist = test_inventory_role_doesnt_exist =
let let
configs = buildInventory { configs = buildInventory {
directory = ./.; self = ./.;
inventory = { inventory = {
modules = clan-core.clanModules; modules = clan-core.clanModules;
services = { services = {
@@ -183,7 +183,7 @@ in
test_inventory_tag_doesnt_exist = test_inventory_tag_doesnt_exist =
let let
configs = buildInventory { configs = buildInventory {
directory = ./.; self = ./.;
inventory = { inventory = {
modules = clan-core.clanModules; modules = clan-core.clanModules;
services = { services = {
@@ -211,7 +211,7 @@ in
test_inventory_disabled_service = test_inventory_disabled_service =
let let
configs = buildInventory { configs = buildInventory {
directory = ./.; self = ./.;
inventory = { inventory = {
modules = clan-core.clanModules; modules = clan-core.clanModules;
services = { services = {

View File

@@ -9,7 +9,7 @@
{ self, clan-core }: { self, clan-core }:
let let
clan = clan-core.lib.buildClan { clan = clan-core.lib.buildClan {
directory = self; inherit self;
meta.name = "test_flake_with_core"; meta.name = "test_flake_with_core";
machines = { machines = {
vm1 = vm1 =

View File

@@ -9,7 +9,7 @@
{ self, clan-core }: { self, clan-core }:
let let
clan = clan-core.lib.buildClan { clan = clan-core.lib.buildClan {
directory = self; inherit self;
meta.name = "test_flake_with_core_and_pass"; meta.name = "test_flake_with_core_and_pass";
machines = { machines = {
vm1 = vm1 =

View File

@@ -9,7 +9,7 @@
{ self, clan-core }: { self, clan-core }:
let let
clan = clan-core.lib.buildClan { clan = clan-core.lib.buildClan {
directory = self; inherit self;
meta.name = "test_flake_with_core_dynamic_machines"; meta.name = "test_flake_with_core_dynamic_machines";
machines = machines =
let let

View File

@@ -29,7 +29,7 @@
specialArgs.self = { specialArgs.self = {
inherit (self) inputs nixosModules packages; inherit (self) inputs nixosModules packages;
}; };
directory = self; inherit self;
machines = { machines = {
# "jon" will be the hostname of the machine # "jon" will be the hostname of the machine
jon = jon =

View File

@@ -6,7 +6,7 @@
{ self, clan-core, ... }: { self, clan-core, ... }:
let let
# Usage see: https://docs.clan.lol # Usage see: https://docs.clan.lol
clan = clan-core.lib.buildClan { directory = self; }; clan = clan-core.lib.buildClan { inherit self; };
in in
{ {
# all machines managed by Clan # all machines managed by Clan

View File

@@ -9,7 +9,7 @@
let let
# Usage see: https://docs.clan.lol # Usage see: https://docs.clan.lol
clan = clan-core.lib.buildClan { clan = clan-core.lib.buildClan {
directory = self; inherit self;
# Ensure this is unique among all clans you want to use. # Ensure this is unique among all clans you want to use.
meta.name = "__CHANGE_ME__"; meta.name = "__CHANGE_ME__";