refactor deployments

This commit is contained in:
Kiara Grouwstra 2025-08-15 19:37:40 +02:00
parent 9d903f3ef7
commit 77d094bf74
Signed by: kiara
SSH key fingerprint: SHA256:COspvLoLJ5WC5rFb9ZDe5urVCkK4LJZOsjfF4duRJFU
3 changed files with 74 additions and 45 deletions

View file

@ -13,7 +13,6 @@ let
./data-model.nix
];
}).config;
nixops4Deployment = inputs.nixops4.modules.nixops4Deployment.default;
inherit (inputs.nixops4.lib) mkDeployment;
in
{
@ -134,6 +133,10 @@ in
};
};
};
deployments.example = {
environment = config.environments.single-nixos-vm;
configuration = config.example-configuration;
};
};
options = {
example-configuration = mkOption {
@ -144,27 +147,27 @@ in
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;
environment = fediversity.environments.single-nixos-vm.resources.operator-environment.login-shell;
result = mkDeployment {
modules = [
(fediversity.environments.single-nixos-vm.deployment fediversity.example-configuration)
fediversity.deployments.example.deployment
];
};
in
{
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;
wheel-required = hello-shell.wheel;
wheel-allowed = environment.wheel;
@ -179,6 +182,7 @@ in
};
deployment = {
inherit (result) _type;
isModule = lib.isFunction fediversity.deployments.example.deployment;
deploymentFunction = lib.isFunction result.deploymentFunction;
getProviders = lib.isFunction result.getProviders;
};
@ -201,6 +205,7 @@ in
_type = "nixops4Deployment";
deploymentFunction = true;
getProviders = true;
isModule = false;
};
};
};

View file

@ -1,6 +1,7 @@
{
lib,
config,
options,
inputs,
...
}:
@ -15,7 +16,7 @@ let
functionTo
;
functionType = import ./function.nix;
functionType = import ./function.nix { inherit lib; };
application-resources = submodule {
options.resources = mkOption {
# 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";
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
config-mapping = mkOption {
description = "Function type for the mapping from application configuration to required resources";
type = submodule functionType;
type = functionType;
readOnly = true;
default = {
input-type = submodule application.config.module;
@ -146,31 +141,13 @@ in
};
resource-mapping = mkOption {
description = "Function type for the mapping from resources to a (NixOps4) deployment";
type = submodule functionType;
readOnly = true;
type = functionType;
# readOnly = true;
default = {
input-type = application-resources;
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";
type = optionType;
readOnly = true;
default = submodule {
default = submodule (configuration: {
options = {
enable = lib.mkEnableOption {
description = "your Fediversity configuration";
@ -192,8 +169,55 @@ in
default = { };
}
) 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
*/
{ config, lib, ... }:
{ lib, ... }:
let
inherit (lib) mkOption types;
inherit (types)
@ -10,7 +10,7 @@ let
optionType
;
in
{
submodule (function: {
options = {
input-type = mkOption {
type = optionType;
@ -20,17 +20,17 @@ in
};
function-type = mkOption {
type = optionType;
readOnly = true;
# readOnly = true;
default = functionTo (submodule {
options = {
input = mkOption {
type = config.input-type;
type = function.config.input-type;
};
output = mkOption {
type = config.output-type;
type = function.config.output-type;
};
};
});
};
};
}
})