From 682031af766634ac1bf959d9d35b00a9f7a1a561 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Fri, 14 Nov 2025 10:17:43 +0100 Subject: [PATCH] unname config Signed-off-by: Kiara Grouwstra --- deployment/run/default.nix | 965 +++++++++++++++++++------------------ 1 file changed, 490 insertions(+), 475 deletions(-) diff --git a/deployment/run/default.nix b/deployment/run/default.nix index 043bc01d..f1339c1d 100644 --- a/deployment/run/default.nix +++ b/deployment/run/default.nix @@ -68,88 +68,91 @@ let httpBackend = mkOption { description = "environment variables to configure the TF HTTP back-end, see "; # type = types.attrsOf (types.either types.str types.int); - type = types.submodule (http-backend: { - options = { - value = mkOption { - readOnly = true; - default = lib.mapAttrs' (k: v: lib.nameValuePair "TF_HTTP_${lib.toUpper k}" (builtins.toString v)) { - inherit (http-backend.config) - address - update_method - lock_address - lock_method - unlock_address - unlock_method - username - password - skip_cert_verification - retry_max - retry_wait_min - retry_wait_max - ; + type = types.submodule ( + { config, ... }: + { + options = { + value = mkOption { + readOnly = true; + default = lib.mapAttrs' (k: v: lib.nameValuePair "TF_HTTP_${lib.toUpper k}" (builtins.toString v)) { + inherit (config) + address + update_method + lock_address + lock_method + unlock_address + unlock_method + username + password + skip_cert_verification + retry_max + retry_wait_min + retry_wait_max + ; + }; + }; + address = mkOption { + description = "The address of the REST endpoint"; + type = str; + }; + update_method = mkOption { + description = "HTTP method to use when updating state."; + type = str; + default = "POST"; + }; + lock_address = mkOption { + description = "The address of the lock REST endpoint."; + type = str; + default = config.address; + }; + lock_method = mkOption { + description = "The HTTP method to use when locking."; + type = str; + default = "LOCK"; + }; + unlock_address = mkOption { + description = "The address of the unlock REST endpoint."; + type = str; + default = config.address; + }; + unlock_method = mkOption { + description = "The HTTP method to use when unlocking."; + type = str; + default = "UNLOCK"; + }; + username = mkOption { + description = "The username for HTTP basic authentication."; + type = str; + default = "basic"; + }; + password = mkOption { + description = "The password for HTTP basic authentication."; + type = str; + default = "fake-secret"; + }; + skip_cert_verification = mkOption { + description = "Whether to skip TLS verification."; + type = str; + default = "false"; + }; + retry_max = mkOption { + description = "The number of HTTP request retries."; + type = types.int; + default = 2; + }; + retry_wait_min = mkOption { + description = "The minimum time in seconds to wait between HTTP request attempts."; + type = types.int; + default = 1; + }; + retry_wait_max = mkOption { + description = "The maximum time in seconds to wait between HTTP request attempts."; + type = types.int; + default = 30; }; }; - address = mkOption { - description = "The address of the REST endpoint"; - type = str; - }; - update_method = mkOption { - description = "HTTP method to use when updating state."; - type = str; - default = "POST"; - }; - lock_address = mkOption { - description = "The address of the lock REST endpoint."; - type = str; - default = http-backend.config.address; - }; - lock_method = mkOption { - description = "The HTTP method to use when locking."; - type = str; - default = "LOCK"; - }; - unlock_address = mkOption { - description = "The address of the unlock REST endpoint."; - type = str; - default = http-backend.config.address; - }; - unlock_method = mkOption { - description = "The HTTP method to use when unlocking."; - type = str; - default = "UNLOCK"; - }; - username = mkOption { - description = "The username for HTTP basic authentication."; - type = str; - default = "basic"; - }; - password = mkOption { - description = "The password for HTTP basic authentication."; - type = str; - default = "fake-secret"; - }; - skip_cert_verification = mkOption { - description = "Whether to skip TLS verification."; - type = str; - default = "false"; - }; - retry_max = mkOption { - description = "The number of HTTP request retries."; - type = types.int; - default = 2; - }; - retry_wait_min = mkOption { - description = "The minimum time in seconds to wait between HTTP request attempts."; - type = types.int; - default = 1; - }; - retry_wait_max = mkOption { - description = "The maximum time in seconds to wait between HTTP request attempts."; - type = types.int; - default = 30; - }; - }; - }); + } + ); }; host-ssh = mkOption { description = "SSH connection info to connect to a single host."; @@ -182,79 +185,82 @@ in { ssh-host = mkOption { description = "A deployment by SSH to update a single existing NixOS host."; - type = submodule (ssh-host: { - options = { - system = mkOption { - description = "The architecture of the system to deploy to."; - type = types.str; - }; - inherit nixos-configuration; - ssh = host-ssh; - caller = mkOption { - description = "The calling module to obtain the NixOS configuration from."; - type = types.str; - }; - args = mkOption { - description = "The arguments with which to call the module to obtain the NixOS configuration."; - type = types.attrs; - }; - deployment-name = mkOption { - description = "The name of the deployment for which to obtain the NixOS configuration."; - type = types.str; - default = "default"; - }; - root-path = mkOption { - description = "The path to the root of the repository."; - type = types.path; - }; - run = mkOption { - type = types.package; - readOnly = true; - default = - let - inherit (ssh-host.config) - system - ssh - caller - args - deployment-name - root-path - ; - inherit (ssh) - host - username - key-file - sshOpts - ; - environment = { - key_file = key-file; - ssh_opts = sshOpts; - inherit + type = submodule ( + { config, ... }: + { + options = { + system = mkOption { + description = "The architecture of the system to deploy to."; + type = types.str; + }; + inherit nixos-configuration; + ssh = host-ssh; + caller = mkOption { + description = "The calling module to obtain the NixOS configuration from."; + type = types.str; + }; + args = mkOption { + description = "The arguments with which to call the module to obtain the NixOS configuration."; + type = types.attrs; + }; + deployment-name = mkOption { + description = "The name of the deployment for which to obtain the NixOS configuration."; + type = types.str; + default = "default"; + }; + root-path = mkOption { + description = "The path to the root of the repository."; + type = types.path; + }; + run = mkOption { + type = types.package; + readOnly = true; + default = + let + inherit (config) + system + ssh + caller + args + deployment-name + root-path + ; + inherit (ssh) host username + key-file + sshOpts ; - nixos_conf = writeConfig { + environment = { + key_file = key-file; + ssh_opts = sshOpts; inherit - system - caller - args - deployment-name - root-path + host + username ; - deployment-type = "ssh-host"; + nixos_conf = writeConfig { + inherit + system + caller + args + deployment-name + root-path + ; + deployment-type = "ssh-host"; + }; }; - }; - in - pkgs.writers.writeBashBin "deploy-sh.sh" - (withPackages [ - pkgs.jq - ]) - '' - env ${withEnv environment} bash ./deployment/run/ssh-single-host/run.sh - ''; + in + pkgs.writers.writeBashBin "deploy-sh.sh" + (withPackages [ + pkgs.jq + ]) + '' + env ${withEnv environment} bash ./deployment/run/ssh-single-host/run.sh + ''; + }; }; - }; - }); + } + ); }; nixops4 = mkOption { description = "A NixOps4 NixOS deployment. For an example, see https://github.com/nixops4/nixops4-nixos/blob/main/example/deployment.nix."; @@ -262,76 +268,79 @@ in }; tf-host = mkOption { description = "A Terraform deployment by SSH to update a single existing NixOS host."; - type = submodule (tf-host: { - options = { - system = mkOption { - description = "The architecture of the system to deploy to."; - type = types.str; - }; - inherit httpBackend nixos-configuration; - ssh = host-ssh; - caller = mkOption { - description = "The calling module to obtain the NixOS configuration from."; - type = types.str; - }; - args = mkOption { - description = "The arguments with which to call the module to obtain the NixOS configuration."; - type = types.attrs; - }; - deployment-name = mkOption { - description = "The name of the deployment for which to obtain the NixOS configuration."; - type = types.str; - }; - root-path = mkOption { - description = "The path to the root of the repository."; - type = types.path; - }; - run = mkOption { - type = types.package; - readOnly = true; - default = - let - inherit (tf-host.config) - system - ssh - caller - args - deployment-name - root-path - httpBackend - ; - inherit (ssh) - host - username - key-file - sshOpts - ; - in - tfApply { - inherit httpBackend; - directory = "tf-single-host"; - environment = { - key_file = key-file; - ssh_opts = sshOpts; - inherit + type = submodule ( + { config, ... }: + { + options = { + system = mkOption { + description = "The architecture of the system to deploy to."; + type = types.str; + }; + inherit httpBackend nixos-configuration; + ssh = host-ssh; + caller = mkOption { + description = "The calling module to obtain the NixOS configuration from."; + type = types.str; + }; + args = mkOption { + description = "The arguments with which to call the module to obtain the NixOS configuration."; + type = types.attrs; + }; + deployment-name = mkOption { + description = "The name of the deployment for which to obtain the NixOS configuration."; + type = types.str; + }; + root-path = mkOption { + description = "The path to the root of the repository."; + type = types.path; + }; + run = mkOption { + type = types.package; + readOnly = true; + default = + let + inherit (config) + system + ssh + caller + args + deployment-name + root-path + httpBackend + ; + inherit (ssh) host username + key-file + sshOpts ; - nixos_conf = writeConfig { + in + tfApply { + inherit httpBackend; + directory = "tf-single-host"; + environment = { + key_file = key-file; + ssh_opts = sshOpts; inherit - system - caller - args - deployment-name - root-path + host + username ; - deployment-type = "tf-host"; + nixos_conf = writeConfig { + inherit + system + caller + args + deployment-name + root-path + ; + deployment-type = "tf-host"; + }; }; }; - }; + }; }; - }; - }); + } + ); }; tf-proxmox-template = mkOption { description = '' @@ -340,81 +349,84 @@ in (https://registry.terraform.io/providers/bpg/proxmox/latest/docs#environment-variables-summary) with role `PVEDatastoreAdmin`. ''; - type = submodule (tf-host: { - options = { - system = mkOption { - description = "The architecture of the system to deploy to."; - type = types.str; - }; - inherit httpBackend nixos-configuration; - ssh = host-ssh; - node-name = mkOption { - description = "the name of the ProxmoX node to use."; - type = types.str; - }; - imageDatastoreId = mkOption { - description = "ID of the datastore of the image."; - type = types.str; - default = "local"; - }; - run = mkOption { - type = types.package; - readOnly = true; - default = - let - inherit (tf-host.config) - system - ssh - httpBackend - node-name - imageDatastoreId - ; - inherit (ssh) - host - ; - machine = import ../nixos.nix { - inherit sources system; - configuration = tf-host.config.nixos-configuration; - }; - name = "fediversity-template"; - - # worse for cross-compilation, better for pre-/post-processing, needs manual `imageSize`, random failures: https://github.com/nix-community/disko/issues/550#issuecomment-2503736973 - raw = "${machine.config.system.build.diskoImages}/main.raw"; - - environment = { - inherit + type = submodule ( + { config, ... }: + { + options = { + system = mkOption { + description = "The architecture of the system to deploy to."; + type = types.str; + }; + inherit httpBackend nixos-configuration; + ssh = host-ssh; + node-name = mkOption { + description = "the name of the ProxmoX node to use."; + type = types.str; + }; + imageDatastoreId = mkOption { + description = "ID of the datastore of the image."; + type = types.str; + default = "local"; + }; + run = mkOption { + type = types.package; + readOnly = true; + default = + let + inherit (config) + system + ssh + httpBackend + node-name + imageDatastoreId + ; + inherit (ssh) host ; - node_name = node-name; - image_datastore_id = imageDatastoreId; - }; - in - lib.trace (lib.strings.toJSON environment) pkgs.writers.writeBashBin "deploy-tf-proxmox-template.sh" - (withPackages [ - pkgs.qemu - ]) - '' - set -e + machine = import ../nixos.nix { + inherit sources system; + configuration = config.nixos-configuration; + }; + name = "fediversity-template"; - # nixos-generate gives the burden of building revisions, while systemd-repart handles partitioning ~~at the burden of version revisions~~ - # .qcow2 is around half the size of .raw, on top of supporting backups - be it apparently at the cost of performance - qemu-img convert -f raw -O qcow2 -C "${raw}" /tmp/${name}.qcow2 + # worse for cross-compilation, better for pre-/post-processing, needs manual `imageSize`, random failures: https://github.com/nix-community/disko/issues/550#issuecomment-2503736973 + raw = "${machine.config.system.build.diskoImages}/main.raw"; - ls -l ${raw} >&2 - ls -l /tmp/${name}.qcow2 >&2 - checksum="$(sha256sum /tmp/${name}.qcow2 | cut -d " " -f1)" + environment = { + inherit + host + ; + node_name = node-name; + image_datastore_id = imageDatastoreId; + }; + in + lib.trace (lib.strings.toJSON environment) pkgs.writers.writeBashBin "deploy-tf-proxmox-template.sh" + (withPackages [ + pkgs.qemu + ]) + '' + set -e - env \ - TF_VAR_image=/tmp/${name}.qcow2 \ - TF_VAR_checksum="$checksum" \ - ${lib.getExe (tfApply { - inherit httpBackend environment; - directory = "tf-proxmox-template"; - })} - ''; + # nixos-generate gives the burden of building revisions, while systemd-repart handles partitioning ~~at the burden of version revisions~~ + # .qcow2 is around half the size of .raw, on top of supporting backups - be it apparently at the cost of performance + qemu-img convert -f raw -O qcow2 -C "${raw}" /tmp/${name}.qcow2 + + ls -l ${raw} >&2 + ls -l /tmp/${name}.qcow2 >&2 + checksum="$(sha256sum /tmp/${name}.qcow2 | cut -d " " -f1)" + + env \ + TF_VAR_image=/tmp/${name}.qcow2 \ + TF_VAR_checksum="$checksum" \ + ${lib.getExe (tfApply { + inherit httpBackend environment; + directory = "tf-proxmox-template"; + })} + ''; + }; }; - }; - }); + } + ); }; tf-proxmox-vm = mkOption { description = '' @@ -423,222 +435,225 @@ in (https://registry.terraform.io/providers/bpg/proxmox/latest/docs#environment-variables-summary) with roles `PVEVMAdmin PVEDatastoreAdmin PVESDNUser`. ''; - type = submodule (tf-host: { - options = { - system = mkOption { - description = "The architecture of the system to deploy to."; - type = types.str; - }; - inherit httpBackend nixos-configuration; - ssh = host-ssh; - caller = mkOption { - description = "The calling module to obtain the NixOS configuration from."; - type = types.str; - }; - args = mkOption { - description = "The arguments with which to call the module to obtain the NixOS configuration."; - type = types.attrs; - }; - deployment-name = mkOption { - description = "The name of the deployment for which to obtain the NixOS configuration."; - type = types.str; - }; - root-path = mkOption { - description = "The path to the root of the repository."; - type = types.path; - }; - node-name = mkOption { - description = "the name of the ProxmoX node to use."; - type = types.str; - }; - bridge = mkOption { - description = "The name of the network bridge (defaults to vmbr0)."; - type = types.str; - default = "vmbr0"; - }; - vlanId = mkOption { - description = "The VLAN identifier."; - type = types.int; - default = 0; - }; - imageDatastoreId = mkOption { - description = "ID of the datastore of the image."; - type = types.str; - default = "local"; - }; - templateId = mkOption { - description = "ID of the template file from which to clone the VM."; - type = types.nullOr types.str; - example = "local:import/template.qcow2"; - }; - vmDatastoreId = mkOption { - description = "ID of the datastore of the VM."; - type = types.str; - default = "local"; - }; - cdDatastoreId = mkOption { - description = "ID of the datastore of the virtual CD-rom drive to use for cloud-init."; - type = types.str; - default = "local"; - }; - ipv4Gateway = mkOption { - description = "Gateway for IPv4."; - type = types.str; - default = ""; - }; - ipv4Address = mkOption { - description = "IPv4 address."; - type = types.nullOr types.str; - default = ""; - }; - ipv6Gateway = mkOption { - description = "Gateway for IPv6."; - type = types.str; - default = ""; - }; - ipv6Address = mkOption { - description = "IPv6 address."; - type = types.str; - default = ""; - }; - run = mkOption { - type = types.package; - readOnly = true; - default = - let - inherit (tf-host.config) - system - ssh - caller - args - deployment-name - httpBackend - root-path - node-name - bridge - vlanId - imageDatastoreId - templateId - vmDatastoreId - cdDatastoreId - ipv4Gateway - ipv4Address - ipv6Gateway - ipv6Address - ; - inherit (ssh) - host - username - key-file - sshOpts - ; - deployment-type = "tf-proxmox-vm"; - nixos_conf = writeConfig { - inherit + type = submodule ( + { config, ... }: + { + options = { + system = mkOption { + description = "The architecture of the system to deploy to."; + type = types.str; + }; + inherit httpBackend nixos-configuration; + ssh = host-ssh; + caller = mkOption { + description = "The calling module to obtain the NixOS configuration from."; + type = types.str; + }; + args = mkOption { + description = "The arguments with which to call the module to obtain the NixOS configuration."; + type = types.attrs; + }; + deployment-name = mkOption { + description = "The name of the deployment for which to obtain the NixOS configuration."; + type = types.str; + }; + root-path = mkOption { + description = "The path to the root of the repository."; + type = types.path; + }; + node-name = mkOption { + description = "the name of the ProxmoX node to use."; + type = types.str; + }; + bridge = mkOption { + description = "The name of the network bridge (defaults to vmbr0)."; + type = types.str; + default = "vmbr0"; + }; + vlanId = mkOption { + description = "The VLAN identifier."; + type = types.int; + default = 0; + }; + imageDatastoreId = mkOption { + description = "ID of the datastore of the image."; + type = types.str; + default = "local"; + }; + templateId = mkOption { + description = "ID of the template file from which to clone the VM."; + type = types.nullOr types.str; + example = "local:import/template.qcow2"; + }; + vmDatastoreId = mkOption { + description = "ID of the datastore of the VM."; + type = types.str; + default = "local"; + }; + cdDatastoreId = mkOption { + description = "ID of the datastore of the virtual CD-rom drive to use for cloud-init."; + type = types.str; + default = "local"; + }; + ipv4Gateway = mkOption { + description = "Gateway for IPv4."; + type = types.str; + default = ""; + }; + ipv4Address = mkOption { + description = "IPv4 address."; + type = types.nullOr types.str; + default = ""; + }; + ipv6Gateway = mkOption { + description = "Gateway for IPv6."; + type = types.str; + default = ""; + }; + ipv6Address = mkOption { + description = "IPv6 address."; + type = types.str; + default = ""; + }; + run = mkOption { + type = types.package; + readOnly = true; + default = + let + inherit (config) system + ssh caller args deployment-name + httpBackend root-path - deployment-type - ; - }; - environment = { - key_file = key-file; - ssh_opts = sshOpts; - inherit - host - nixos_conf + node-name bridge + vlanId + imageDatastoreId + templateId + vmDatastoreId + cdDatastoreId + ipv4Gateway + ipv4Address + ipv6Gateway + ipv6Address ; - node_name = node-name; - ssh_user = username; - vlan_id = vlanId; - image_datastore_id = imageDatastoreId; - template_id = templateId; - vm_datastore_id = vmDatastoreId; - cd_datastore_id = cdDatastoreId; - ipv4_gateway = ipv4Gateway; - ipv4_address = ipv4Address; - ipv6_gateway = ipv6Gateway; - ipv6_address = ipv6Address; - }; - in - lib.trace (lib.strings.toJSON environment) (tfApply { - inherit httpBackend environment; - directory = "tf-proxmox-vm"; - dependentDirs = [ "tf-single-host" ]; - }); + inherit (ssh) + host + username + key-file + sshOpts + ; + deployment-type = "tf-proxmox-vm"; + nixos_conf = writeConfig { + inherit + system + caller + args + deployment-name + root-path + deployment-type + ; + }; + environment = { + key_file = key-file; + ssh_opts = sshOpts; + inherit + host + nixos_conf + bridge + ; + node_name = node-name; + ssh_user = username; + vlan_id = vlanId; + image_datastore_id = imageDatastoreId; + template_id = templateId; + vm_datastore_id = vmDatastoreId; + cd_datastore_id = cdDatastoreId; + ipv4_gateway = ipv4Gateway; + ipv4_address = ipv4Address; + ipv6_gateway = ipv6Gateway; + ipv6_address = ipv6Address; + }; + in + lib.trace (lib.strings.toJSON environment) (tfApply { + inherit httpBackend environment; + directory = "tf-proxmox-vm"; + dependentDirs = [ "tf-single-host" ]; + }); + }; }; - }; - }); + } + ); }; tf-netbox-store-ips = mkOption { description = "Store a range of IPs in a Netbox instance."; - type = submodule (tf-netbox-store-ips: { - options = { - inherit httpBackend; - startAddress = mkOption { - description = "Start of the IP range."; - type = types.str; - example = "10.0.0.1/24"; - }; - endAddress = mkOption { - description = "End of the IP range."; - type = types.str; - example = "10.0.0.50/24"; - }; - run = mkOption { - type = types.package; - readOnly = true; - default = - let - inherit (tf-netbox-store-ips.config) - httpBackend - startAddress - endAddress - ; - in - tfApply { - inherit httpBackend; - directory = "tf-netbox-store-ips"; - environment = { - start_address = startAddress; - end_address = endAddress; + type = submodule ( + { config, ... }: + { + options = { + inherit httpBackend; + startAddress = mkOption { + description = "Start of the IP range."; + type = types.str; + example = "10.0.0.1/24"; + }; + endAddress = mkOption { + description = "End of the IP range."; + type = types.str; + example = "10.0.0.50/24"; + }; + run = mkOption { + type = types.package; + readOnly = true; + default = + let + inherit (config) + httpBackend + startAddress + endAddress + ; + in + tfApply { + inherit httpBackend; + directory = "tf-netbox-store-ips"; + environment = { + start_address = startAddress; + end_address = endAddress; + }; }; - }; + }; }; - }; - }); + } + ); }; tf-netbox-get-ip = mkOption { description = "Get an available IP from a Netbox instance."; - type = submodule (tf-netbox-get-ip: { - options = { - inherit httpBackend; - run = mkOption { - type = types.package; - readOnly = true; - default = - let - inherit (tf-netbox-get-ip.config) - httpBackend - ; - in - tfApply { - inherit httpBackend; + type = submodule ( + { config, ... }: + { + options = { + inherit httpBackend; + run = mkOption { + type = types.package; + readOnly = true; + default = tfApply { + inherit (config) httpBackend; directory = "tf-netbox-get-ip"; environment = { }; }; + }; }; - }; - }); + } + ); }; octodns-zone = mkOption { description = "Manage DNS records."; type = submodule ( - octodns-zone: + { config, ... }: let dns = pkgs.callPackage sources."dns.nix" { }; in @@ -715,14 +730,14 @@ in }; configuration = mkOption { type = submodule { - options = octodns-zone.config.providers.${octodns-zone.config.provider}.configuration; + options = config.providers.${config.provider}.configuration; }; default = { }; }; package = mkOption { type = types.package; example = "The package of the OctoDNS provider to deploy to, see ."; - default = pkgs.octodns-providers.${octodns-zone.config.provider}; + default = pkgs.octodns-providers.${config.provider}; }; packages = mkOption { type = types.listOf types.package; @@ -733,7 +748,7 @@ in .withProviders (_: [ pkgs.octodns-providers.bind - octodns-zone.config.package + config.package ]) ) ]; @@ -742,7 +757,7 @@ in type = types.path; default = let - inherit (octodns-zone.config) + inherit (config) domain zone providers @@ -762,7 +777,7 @@ in { inherit class; } - // octodns-zone.config.configuration + // config.configuration // (lib.genAttrs secrets (k: "env/${lib.toUpper "${provider}_${k}"}")); config = { file_extension = ""; @@ -789,7 +804,7 @@ in type = types.package; default = let - inherit (octodns-zone.config) + inherit (config) packages conf provider @@ -805,7 +820,7 @@ in type = types.package; default = let - inherit (octodns-zone.config) + inherit (config) packages conf provider