diff --git a/default.nix b/default.nix index 7c536a03..ea7b2557 100644 --- a/default.nix +++ b/default.nix @@ -9,6 +9,8 @@ let git-hooks gitignore ; + inherit (import sources.flake-inputs) import-flake; + inputs = (import-flake { src = ./.; }).inputs; inherit (pkgs) lib; pre-commit-check = (import "${git-hooks}/nix" { @@ -67,6 +69,7 @@ in # re-export inputs so they can be overridden granularly # (they can't be accessed from the outside any other way) inherit + inputs sources system pkgs diff --git a/deployment/data-model-test.nix b/deployment/data-model-test.nix index 16a5caaf..3f24df94 100644 --- a/deployment/data-model-test.nix +++ b/deployment/data-model-test.nix @@ -1,9 +1,12 @@ let - inherit (import ../default.nix { }) pkgs; + inherit (import ../default.nix { }) pkgs inputs; inherit (pkgs) lib; eval = module: (lib.evalModules { + specialArgs = { + inherit inputs; + }; modules = [ module ./data-model.nix @@ -11,8 +14,6 @@ let }).config; in { - _class = "nix-unit"; - test-eval = { expr = let diff --git a/deployment/data-model.nix b/deployment/data-model.nix index 81ce96c2..af6eda78 100644 --- a/deployment/data-model.nix +++ b/deployment/data-model.nix @@ -1,6 +1,7 @@ { lib, config, + inputs, ... }: let @@ -15,6 +16,20 @@ let submodule str ; + + functionType = import ./interface.nix; + application-resources = { + options.resources = mkOption { + type = attrsOf ( + attrTag ( + lib.mapAttrs' (name: resource: { + ${name} = mkOption { type = resource.consumer; }; + }) config.resources + ) + ); + }; + }; + nixops4Deployment = inputs.nixops4.modules.nixops4Deployment.default; in { options = { @@ -51,7 +66,19 @@ in }; config-mapping = mkOption { description = "Mapping of application configuration to deployment resources, a description of what an application needs to run"; - # TODO: type = (submodule application.config.module) -> (attrsOf (attrTag (lib.mapAttrs' (name: resource: { ${name} = mkOption { type = resource.consumer; }; }) config.resources))) /* something like that */ + type = application.config.function.implementation; + }; + # TODO: somewhere we still need to + # - apply = { implementation = config-mapping; input = ; } + # - apply.output + function = mkOption { + description = "Function type for the mapping from application configuration to required resources"; + type = submodule functionType; + readOnly = true; + default = { + input-type = application.config.module; + output-type = application-resources; + }; }; }; }) @@ -75,8 +102,18 @@ in }; resource-mapping = mkOption { description = "Mapping of resources required by applications to available resources; the result can be deployed"; + type = environment.config.function.implementation; # TODO: type = consumer-resources /* same as the output of application.config-mapping, should be in a `let` */ -> nixops4Deployment }; + function = mkOption { + description = "Function type for the mapping from resources to a (NixOps4) deployment"; + type = submodule functionType; + readOnly = true; + default = { + input-type = application-resources; + output-type = submodule nixops4Deployment; + }; + }; }; }) ); diff --git a/deployment/interface.nix b/deployment/interface.nix new file mode 100644 index 00000000..225526d1 --- /dev/null +++ b/deployment/interface.nix @@ -0,0 +1,49 @@ +/** + Modular function type +*/ +{ config, ... }: +{ + options = { + input-type = mkOption { + type = deferredModule; + }; + output-type = mkOption { + type = deferredModule; + }; + implementation = mkOption { + type = optionType; + readOnly = true; + default = implementationTo ( + submodule (implementation: { + options = { + input = mkOption { + type = submodule config.input-type; + }; + output = mkOption { + type = submodule config.output-type; + }; + }; + }) + ); + }; + apply = mkOption { + type = optionType; + readOnly = true; + default = submodule (apply: { + options = { + implementation = mkOption { + type = config.implementation; + }; + input = mkOption { + type = submodule config.input-type; + }; + output = mkOption { + type = submodule config.output-type; + readOnly = true; + default = (apply.config.implementation apply.config.input).output; + }; + }; + }); + }; + }; +}