From a41498108911c19d25c3030199253c1c0a0682c6 Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Mon, 7 Oct 2024 22:31:46 +0200 Subject: [PATCH] Init: eval clanmodule interface with roles --- lib/default.nix | 5 +- lib/eval-clan-modules/default.nix | 74 +++++++++++++++++++++++++-- lib/inventory/interface-to-schema.nix | 5 +- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/lib/default.nix b/lib/default.nix index 23556ee91..1faa640d0 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -4,8 +4,11 @@ nixpkgs, ... }: +let + eval = import ./eval-clan-modules { inherit clan-core nixpkgs lib; }; +in { - evalClanModules = import ./eval-clan-modules { inherit clan-core nixpkgs lib; }; + inherit (eval) evalClanModules evalClanModulesWithRoles; buildClan = import ./build-clan { inherit lib nixpkgs clan-core; }; facts = import ./facts.nix { inherit lib; }; inventory = import ./inventory { inherit lib clan-core; }; diff --git a/lib/eval-clan-modules/default.nix b/lib/eval-clan-modules/default.nix index 50c5c2c9b..f82009a31 100644 --- a/lib/eval-clan-modules/default.nix +++ b/lib/eval-clan-modules/default.nix @@ -19,7 +19,7 @@ let # This function takes a list of module names and evaluates them # evalClanModules :: [ String ] -> { config, options, ... } - evalClanModules = + evalClanModulesLegacy = modulenames: let evaled = lib.evalModules { @@ -32,6 +32,74 @@ let ] ++ (map (name: clanModules.${name}) modulenames); }; in - evaled; + lib.warn '' + EvalClanModules doesn't respect role specific interfaces. + + The following {module}/default.nix file trying to be imported. + + Modules: ${builtins.toJSON modulenames} + + This might result in incomplete or incorrect interfaces. + + FIX: Use evalClanModuleWithRole instead. + '' evaled; + + /* + This function takes a list of module names and evaluates them + Returns a set of interfaces as described below: + + Fn :: { ${moduleName} = Module; } -> { + ${moduleName} :: { + ${roleName}: JSONSchema + } + } + */ + evalClanModulesWithRoles = + clanModules: + let + getRoles = + modulePath: + let + rolesDir = "${modulePath}/roles"; + in + if builtins.pathExists rolesDir then + lib.pipe rolesDir [ + builtins.readDir + (lib.filterAttrs (_n: v: v == "regular")) + lib.attrNames + (lib.filter (fileName: lib.hasSuffix ".nix" fileName)) + (map (fileName: lib.removeSuffix ".nix" fileName)) + ] + else + [ ]; + res = builtins.mapAttrs ( + moduleName: module: + let + # module must be a path to the clanModule root by convention + # See: clanModules/flake-module.nix + roles = + assert lib.isPath module; + getRoles module; + in + lib.listToAttrs ( + lib.map (role: { + name = role; + value = + (lib.evalModules { + modules = [ + baseModule + clan-core.nixosModules.clanCore + # Role interface + (module + "/roles/${role}.nix") + ]; + }).options.clan.${moduleName} or { }; + }) roles + ) + ) clanModules; + in + res; in -evalClanModules +{ + evalClanModules = evalClanModulesLegacy; + inherit evalClanModulesWithRoles; +} diff --git a/lib/inventory/interface-to-schema.nix b/lib/inventory/interface-to-schema.nix index 709a0d2d7..0c2a7f215 100644 --- a/lib/inventory/interface-to-schema.nix +++ b/lib/inventory/interface-to-schema.nix @@ -94,9 +94,10 @@ let rolesOf = moduleName: let + # null | [ string ] roles = getRoles self.clanModules.${moduleName}; in - if roles == null then [ "default" ] else roles; + if roles == null then [ ] else roles; moduleServices = lib.mapAttrs moduleToService ( lib.filterAttrs (n: _v: rolesOf n != [ ]) modulesSchema ); @@ -129,4 +130,6 @@ in } */ schemaWithModules = schema; + + inherit modulesSchema; }