From 3ec853a32af6ee2f60f31a853c74b274b9020660 Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Tue, 1 Jul 2025 12:16:29 +0200 Subject: [PATCH] WIP: implement data model as in diagram this doesn't update the tests yet because we don't have all the data types in place anyway yet, and I still need to come up with testable examples. --- deployment/data-model.nix | 214 +++++++++++--------------------------- 1 file changed, 60 insertions(+), 154 deletions(-) diff --git a/deployment/data-model.nix b/deployment/data-model.nix index 2a52728c..81ce96c2 100644 --- a/deployment/data-model.nix +++ b/deployment/data-model.nix @@ -4,176 +4,82 @@ ... }: let - inherit (lib) - attrNames - mapAttrs - mkOption - genAttrs - ; + inherit (lib) mkOption; inherit (lib.types) attrsOf attrTag - deferredModule + deferredModuleWith mergeTypes nullOr submoduleWith submodule str ; - provider = mkOption { - description = "The NixOS module of a provider"; - type = deferredModule; - default = { - _class = "nixos"; - }; - }; - runtime-environment = attrTag ( - mapAttrs - ( - name: - option@{ type, ... }: - mkOption ( - option - // { - type = mergeTypes type (submodule { - options.module = mkOption { - description = "The NixOS module of the provider"; - type = deferredModule; - default = config.providers.${name}; - readOnly = true; - }; - }); - } - ) - ) - { - vm = { - description = "A VM to deploy to."; - type = submodule { - options = { - }; - }; - }; - single-ssh-host = { - description = "A single host to deploy to by SSH."; - type = submodule { - options = { - ssh = mkOption { - description = "SSH connection info"; - type = submodule { - options = { - host = mkOption { - description = "the host to access by SSH"; - type = str; - }; - username = mkOption { - description = "the SSH user to use"; - type = nullOr str; - default = null; - }; - authentication = mkOption { - description = "authentication method"; - type = attrsOf (attrTag { - private-key = mkOption { - description = "path to the user's SSH private key"; - type = str; - example = "/root/.ssh/id_ed25519"; - }; - password = mkOption { - description = "SSH password"; - # TODO: mark as sensitive - type = str; - }; - }); - }; - }; - }; - }; - }; - }; - }; - } - ); - resource = attrTag { - runtime-environment = mkOption { - description = "A run-time environment one may deploy a NixOS configuration to."; - type = runtime-environment; - }; - }; - application = submoduleWith { - description = "A Fediversity application"; - modules = [ - { - options = { - module = mkOption { - description = '' - The NixOS module to configure the application. - ''; - type = deferredModule; - }; - }; - } - ]; - }; - deployment = submoduleWith { - description = "A deployment of a configuration of applications to a run-time environment"; - modules = [ - { - options = { - # the `applications` option consists of configuration for the above applications - module = mkOption { - description = '' - Configuration to be deployed - ''; - type = deferredModule; - }; - runtime-environment = mkOption { - description = "The run-time environment to deploy to"; - type = runtime-environment; - }; - }; - } - ]; - }; - migration = submoduleWith { - description = "Migration of a Fediversity deployment to a Fediversity run-time environment"; - modules = [ - { - options = { - deployment = mkOption { - description = "Deployment to migrate"; - type = deployment; - }; - runtime-environment = mkOption { - description = "Run-time environment to migrate the deployment to"; - type = runtime-environment; - }; - }; - } - ]; - }; in { options = { - providers = mkOption { - description = "Collection of providers for run-time environments to deploy applications to"; - type = attrTag (genAttrs (attrNames runtime-environment.nestedTypes) (_: provider)); - }; resources = mkOption { - description = "Collection of resources for use in Fediversity applications"; - type = attrsOf resource; + description = "Collection of deployment resources that can be configured by hosting providers and required by applications"; + type = attrsOf ( + submodule ( + { config, ... }: + { + _class = "fediversity-resource"; + options = { + consumer = mkOption { + description = "Configuration of the resource by an application, a description of how the resource is consumed"; + type = deferredModuleWith { staticModules = [ { _class = "fediversity-resource-consumer"; } ]; }; + }; + provider = mkOption { + description = "Configuration of the resource by the hosting provider, a description of how the resource is made available"; + type = deferredModuleWith { staticModules = [ { _class = "fediversity-resource-provider"; } ]; }; + }; + }; + } + ) + ); }; applications = mkOption { - description = "Collection of (available) Fediversity applications"; - type = attrsOf application; + description = "Collection of Fediversity applications"; + type = attrsOf ( + submodule (application: { + _class = "fediversity-application"; + options = { + module = mkOption { + description = "Operator-facing configuration options for the application"; + type = deferredModuleWith { staticModules = [ { _class = "fediversity-application-config"; } ]; }; + }; + 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 */ + }; + }; + }) + ); }; - deployments = mkOption { - description = "Deployment of a configuration of applications to a run-time environment"; - type = attrsOf deployment; - }; - migrations = mkOption { - description = "Migrations from Fediversity deployments to Fediversity run-time environments"; - type = attrsOf migration; + environments = mkOption { + description = "Run-time environments for Fediversity applications to be deployed to"; + type = attrsOf ( + submodule (environment: { + _class = "fediversity-environment"; + options = { + resources = mkOption { + description = "Resources made available by the hosting provider"; + type = attrsOf ( + attrTag ( + lib.mapAttrs' (name: resource: { + ${name} = mkOption { type = resource.provider; }; + }) config.resources + ) + ); + }; + resource-mapping = mkOption { + description = "Mapping of resources required by applications to available resources; the result can be deployed"; + # TODO: type = consumer-resources /* same as the output of application.config-mapping, should be in a `let` */ -> nixops4Deployment + }; + }; + }) + ); }; }; }