try to modularly apply functions, hoping to fix input type checks

fix types
This commit is contained in:
Kiara Grouwstra 2025-08-15 19:37:40 +02:00
parent 9c219341b1
commit ed240f0db1
Signed by: kiara
SSH key fingerprint: SHA256:COspvLoLJ5WC5rFb9ZDe5urVCkK4LJZOsjfF4duRJFU
3 changed files with 70 additions and 43 deletions

View file

@ -13,7 +13,6 @@ let
./data-model.nix ./data-model.nix
]; ];
}).config; }).config;
nixops4Deployment = inputs.nixops4.modules.nixops4Deployment.default;
inherit (inputs.nixops4.lib) mkDeployment; inherit (inputs.nixops4.lib) mkDeployment;
in in
{ {
@ -134,6 +133,10 @@ in
}; };
}; };
}; };
deployments.example = {
environment = config.environments.single-nixos-vm;
configuration = config.example-configuration;
};
}; };
options = { options = {
example-configuration = mkOption { example-configuration = mkOption {
@ -144,27 +147,27 @@ in
applications.hello.enable = true; applications.hello.enable = true;
}; };
}; };
example-deployment = mkOption {
type = types.submodule nixops4Deployment;
readOnly = true;
default = config.environments.single-nixos-vm.deployment config.example-configuration;
};
}; };
} }
); );
resources = fediversity.applications.hello.resources fediversity.example-configuration.applications.hello; resources = fediversity.example-configuration.required-resources.hello;
hello-shell = resources.resources.hello.login-shell; hello-shell = resources.resources.hello.login-shell;
environment = fediversity.environments.single-nixos-vm.resources.operator-environment.login-shell; environment = fediversity.environments.single-nixos-vm.resources.operator-environment.login-shell;
result = mkDeployment { result = mkDeployment {
modules = [ modules = [
(fediversity.environments.single-nixos-vm.deployment fediversity.example-configuration) fediversity.deployments.example.deployment
]; ];
}; };
in in
{ {
number-of-resources = with lib; length (attrNames fediversity.resources); number-of-resources = with lib; length (attrNames fediversity.resources);
inherit (fediversity) example-configuration; # XXX: nix-unit unlike nix-build seems to hit infinite recursions on
# evaluation of package paths, so we avoid evaluating
# fediversity.example-configuration.required-resources.hello.resources.hello.login-shell.packages.hello
example-configuration = {
inherit (fediversity.example-configuration) enable applications;
};
hello-package-exists = hello-shell.packages ? hello; hello-package-exists = hello-shell.packages ? hello;
wheel-required = hello-shell.wheel; wheel-required = hello-shell.wheel;
wheel-allowed = environment.wheel; wheel-allowed = environment.wheel;

View file

@ -1,6 +1,7 @@
{ {
lib, lib,
config, config,
options,
inputs, inputs,
... ...
}: }:
@ -15,7 +16,7 @@ let
functionTo functionTo
; ;
functionType = import ./function.nix; functionType = import ./function.nix { inherit lib; };
application-resources = submodule { application-resources = submodule {
options.resources = mkOption { options.resources = mkOption {
# TODO: maybe transpose, and group the resources by type instead # TODO: maybe transpose, and group the resources by type instead
@ -101,16 +102,10 @@ in
description = "Mapping of application configuration to deployment resources, a description of what an application needs to run"; description = "Mapping of application configuration to deployment resources, a description of what an application needs to run";
type = application.config.config-mapping.function-type; type = application.config.config-mapping.function-type;
}; };
resources = mkOption {
description = "Compute resources required by an application";
type = functionTo application.config.config-mapping.output-type;
readOnly = true;
default = input: (application.config.implementation input).output;
};
# TODO(@fricklerhandwerk): this needs a better name, it's just the type # TODO(@fricklerhandwerk): this needs a better name, it's just the type
config-mapping = mkOption { config-mapping = mkOption {
description = "Function type for the mapping from application configuration to required resources"; description = "Function type for the mapping from application configuration to required resources";
type = submodule functionType; type = functionType;
readOnly = true; readOnly = true;
default = { default = {
input-type = submodule application.config.module; input-type = submodule application.config.module;
@ -146,31 +141,13 @@ in
}; };
resource-mapping = mkOption { resource-mapping = mkOption {
description = "Function type for the mapping from resources to a (NixOps4) deployment"; description = "Function type for the mapping from resources to a (NixOps4) deployment";
type = submodule functionType; type = functionType;
readOnly = true; readOnly = true;
default = { default = {
input-type = application-resources; input-type = application-resources;
output-type = nixops4Deployment; output-type = nixops4Deployment;
}; };
}; };
# TODO(@fricklerhandwerk): maybe this should be a separate thing such as `fediversity-setup`,
# which makes explicit which applications and environments are available.
# then the deployments can simply be the result of the function application baked into this module.
deployment = mkOption {
description = "Generate a deployment from a configuration, by applying an environment's resource policies to the applications' resource mappings";
type = functionTo (environment.config.resource-mapping.output-type);
readOnly = true;
default =
cfg:
# TODO: check cfg.enable.true
let
required-resources = lib.mapAttrs (
name: application-settings: config.applications.${name}.resources application-settings
) cfg.applications;
in
(environment.config.implementation required-resources).output;
};
}; };
}) })
); );
@ -179,7 +156,7 @@ in
description = "Configuration type declaring options to be set by operators"; description = "Configuration type declaring options to be set by operators";
type = optionType; type = optionType;
readOnly = true; readOnly = true;
default = submodule { default = submodule (configuration: {
options = { options = {
enable = lib.mkEnableOption { enable = lib.mkEnableOption {
description = "your Fediversity configuration"; description = "your Fediversity configuration";
@ -192,8 +169,55 @@ in
default = { }; default = { };
} }
) config.applications; ) config.applications;
required-resources = mkOption {
description = "The deployment's required resources by application";
type = submodule {
options = lib.mapAttrs (
name: _application:
mkOption {
description = "Resources required for ${name}";
type = config.applications.${name}.config-mapping.output-type;
}
) config.applications;
};
readOnly = true;
default = lib.mapAttrs (
# FIXME: in nix-unit invoking the implementation somehow triggers an infinite recursion,
# tho my trace statements so far got triggered just once
name: application-settings: (config.applications.${name}.implementation application-settings).output
) configuration.config.applications;
};
}; };
}; });
};
deployments = mkOption {
description = "Deployment of a configuration of applications to a run-time environment.";
type = attrsOf (
submodule (deployment: {
options = {
configuration = mkOption {
description = "Configuration to be deployed";
type = config.configuration;
};
environment = mkOption {
description = "The run-time environment to deploy to";
type = options.environments.type.nestedTypes.elemType;
};
# TODO(@fricklerhandwerk): maybe this should be a separate thing such as `fediversity-setup`,
# which makes explicit which applications and environments are available.
# then the deployments can simply be the result of the function application baked into this module.
deployment = mkOption {
description = "Generate a deployment from a configuration, by applying an environment's resource policies to the applications' resource mappings";
type = deployment.config.environment.resource-mapping.output-type;
readOnly = true;
# TODO: check cfg.enable.true
default =
(deployment.config.environment.implementation deployment.config.configuration.required-resources)
.output;
};
};
})
);
}; };
}; };
} }

View file

@ -1,7 +1,7 @@
/** /**
Modular function type Modular function type
*/ */
{ config, lib, ... }: { lib, ... }:
let let
inherit (lib) mkOption types; inherit (lib) mkOption types;
inherit (types) inherit (types)
@ -10,7 +10,7 @@ let
optionType optionType
; ;
in in
{ submodule (function: {
options = { options = {
input-type = mkOption { input-type = mkOption {
type = optionType; type = optionType;
@ -24,13 +24,13 @@ in
default = functionTo (submodule { default = functionTo (submodule {
options = { options = {
input = mkOption { input = mkOption {
type = config.input-type; type = function.config.input-type;
}; };
output = mkOption { output = mkOption {
type = config.output-type; type = function.config.output-type;
}; };
}; };
}); });
}; };
}; };
} })