diff --git a/lib/build-clan/interface.nix b/lib/build-clan/interface.nix index fc61197e7..b999c33e4 100644 --- a/lib/build-clan/interface.nix +++ b/lib/build-clan/interface.nix @@ -174,6 +174,7 @@ in inventoryFile = lib.mkOption { type = lib.types.raw; }; # The machine 'imports' generated by the inventory per machine inventoryClass = lib.mkOption { type = lib.types.raw; }; + evalServiceSchema = lib.mkOption { }; # clan-core's modules clanModules = lib.mkOption { type = lib.types.raw; }; source = lib.mkOption { type = lib.types.raw; }; diff --git a/lib/build-clan/module.nix b/lib/build-clan/module.nix index 169c058e0..7a4a0c126 100644 --- a/lib/build-clan/module.nix +++ b/lib/build-clan/module.nix @@ -205,6 +205,21 @@ in inherit inventoryClass; + # Endpoint that can be called to get a service schema + evalServiceSchema = + {moduleSpec}: + let + resolvedModule = clan-core.clanLib.inventory.resolveModule { + inherit moduleSpec; + flakeInputs = config.self.inputs; + localModuleSet = config.inventory.modules; + }; + in + (clan-core.clanLib.inventory.evalClanService { + modules = [ resolvedModule ]; + prefix = [ ]; + }).config.result.api.schema; + # TODO: unify this interface # We should have only clan.modules. (consistent with clan.templates) inherit (clan-core) clanModules clanLib; diff --git a/lib/inventory/default.nix b/lib/inventory/default.nix index d53a20e06..9b3112f37 100644 --- a/lib/inventory/default.nix +++ b/lib/inventory/default.nix @@ -3,7 +3,7 @@ let services = clanLib.callLib ./distributed-service/inventory-adapter.nix { }; in { - inherit (services) evalClanService mapInstances; + inherit (services) evalClanService mapInstances resolveModule; inherit (import ./build-inventory { inherit lib clanLib; }) buildInventory; interface = ./build-inventory/interface.nix; # Returns the list of machine names diff --git a/lib/inventory/distributed-service/inventory-adapter.nix b/lib/inventory/distributed-service/inventory-adapter.nix index bbedc467f..201831c47 100644 --- a/lib/inventory/distributed-service/inventory-adapter.nix +++ b/lib/inventory/distributed-service/inventory-adapter.nix @@ -27,9 +27,53 @@ let }) ] ++ modules; }); + + resolveModule = + { + moduleSpec, + flakeInputs, + localModuleSet, + }: + let + # TODO: + resolvedModuleSet = + # If the module.name is self then take the modules defined in the flake + # Otherwise its an external input which provides the modules via 'clan.modules' attribute + if moduleSpec.input == null then + localModuleSet + else + let + input = + flakeInputs.${moduleSpec.input} or (throw '' + Flake doesn't provide input with name '${moduleSpec.input}' + + Choose one of the following inputs: + - ${ + builtins.concatStringsSep "\n- " ( + lib.attrNames (lib.filterAttrs (_name: input: input ? clan) flakeInputs) + ) + } + + To import a local module from 'inventory.modules' remove the 'input' attribute from the module definition + Remove the following line from the module definition: + + ... + - module.input = "${moduleSpec.input}" + + ''); + clanAttrs = + input.clan or (throw "It seems the flake input ${moduleSpec.input} doesn't export any clan resources"); + in + clanAttrs.modules; + + resolvedModule = + resolvedModuleSet.${moduleSpec.name} + or (throw "flake doesn't provide clan-module with name ${moduleSpec.name}"); + in + resolvedModule; in { - inherit evalClanService; + inherit evalClanService resolveModule; mapInstances = { # This is used to resolve the module imports from 'flake.inputs' @@ -45,42 +89,11 @@ in importedModuleWithInstances = lib.mapAttrs ( instanceName: instance: let - # TODO: - resolvedModuleSet = - # If the module.name is self then take the modules defined in the flake - # Otherwise its an external input which provides the modules via 'clan.modules' attribute - if instance.module.input == null then - inventory.modules - else - let - input = - flakeInputs.${instance.module.input} or (throw '' - Flake doesn't provide input with name '${instance.module.input}' - - Choose one of the following inputs: - - ${ - builtins.concatStringsSep "\n- " ( - lib.attrNames (lib.filterAttrs (_name: input: input ? clan) flakeInputs) - ) - } - - To import a local module from 'inventory.modules' remove the 'input' attribute from the module definition - Remove the following line from the module definition: - - ... - - module.input = "${instance.module.input}" - - - ''); - clanAttrs = - input.clan - or (throw "It seems the flake input ${instance.module.input} doesn't export any clan resources"); - in - clanAttrs.modules; - - resolvedModule = - resolvedModuleSet.${instance.module.name} - or (throw "flake doesn't provide clan-module with name ${instance.module.name}"); + resolvedModule = resolveModule { + moduleSpec = instance.module; + localModuleSet = inventory.modules; + inherit flakeInputs; + }; # Every instance includes machines via roles # :: { client :: ... }