From 334719f529f9ba3a535c1808d79af2229f0be1f9 Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Fri, 4 Apr 2025 12:10:44 +0200 Subject: [PATCH] WIP: actually typecheck it's still broken because of the default values, need to look at it more closely --- deployment/default.nix | 299 ++++++++++-------- .../templates/partials/deployment_result.html | 2 +- panel/src/panel/views.py | 2 + 3 files changed, 164 insertions(+), 139 deletions(-) diff --git a/deployment/default.nix b/deployment/default.nix index 4d8aab01..baed4ce2 100644 --- a/deployment/default.nix +++ b/deployment/default.nix @@ -31,152 +31,175 @@ ## Information on the specific deployment that we request. ## This is the information coming from the FediPanel. -config: +deployment-configuration: let inherit (lib) mkIf; - # TODO(@fricklerhandwerk): misusing this will produce obscure errors that will be truncated by NixOps4 - panelConfig = (lib.evalModules { modules = [ ./options.nix ]; }).config; in ## Regular arguments of a NixOps4 deployment module. -{ providers, ... }: - +{ config, providers, ... }: +let + panelConfig = config.deployment; +in { - providers = { - inherit (nixops4.modules.nixops4Provider) local; + options = { + deployment = lib.mkOption { + description = '' + Configuration to be deployed + ''; + # XXX(@fricklerhandwerk): + # misusing this will produce obscure errors that will be truncated by NixOps4 + type = lib.types.submodule ./options.nix; + }; }; - resources = - let - ## NOTE: All of these secrets are publicly available in this source file - ## and will end up in the Nix store. We don't care as they are only ever - ## used for testing anyway. - ## - ## FIXME: Generate and store in NixOps4's state. - mastodonS3KeyConfig = - { pkgs, ... }: - { - s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK3515373e4c851ebaad366558"; - s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34"; - }; - peertubeS3KeyConfig = - { pkgs, ... }: - { - s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK1f9feea9960f6f95ff404c9b"; - s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395"; - }; - pixelfedS3KeyConfig = - { pkgs, ... }: - { - s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GKb5615457d44214411e673b7b"; - s3SecretKeyFile = pkgs.writeText "s3SecretKey" "5be6799a88ca9b9d813d1a806b64f15efa49482dbe15339ddfaf7f19cf434987"; - }; - - makeConfigurationResource = resourceModule: config: { - type = providers.local.exec; - imports = [ - nixops4-nixos.modules.nixops4Resource.nixos - resourceModule - - { - ## NOTE: With NixOps4, there are several levels and all of them live - ## in the NixOS module system: - ## - ## 1. Each NixOps4 deployment is a module. - ## 2. Each NixOps4 resource is a module. This very comment is - ## inside an attrset imported as a module in a resource. - ## 3. Each NixOps4 'configuration' resource contains an attribute - ## 'nixos.module', itself a NixOS configuration module. - nixos.module = - { ... }: - { - imports = [ - config - fediversity - ]; - }; - } - ]; - }; - - in - - { - garage-configuration = makeConfigurationResource garageConfigurationResource ( - { pkgs, ... }: - mkIf (panelConfig.mastodon.enable || panelConfig.peertube.enable || panelConfig.pixelfed.enable) { - fediversity = { - inherit (panelConfig) domain; - garage.enable = true; - pixelfed = pixelfedS3KeyConfig { inherit pkgs; }; - mastodon = mastodonS3KeyConfig { inherit pkgs; }; - peertube = peertubeS3KeyConfig { inherit pkgs; }; - }; - } - ); - - mastodon-configuration = makeConfigurationResource mastodonConfigurationResource ( - { pkgs, ... }: - mkIf panelConfig.mastodon.enable { - fediversity = { - inherit (panelConfig) domain; - temp.initialUser = { - inherit (panelConfig.initialUser) username email displayName; - # FIXME: disgusting, but nvm, this is going to be replaced by - # proper central authentication at some point - passwordFile = pkgs.writeText "password" panelConfig.initialUser.password; - }; - - mastodon = mastodonS3KeyConfig { inherit pkgs; } // { - enable = true; - }; - - temp.cores = 1; # FIXME: should come from NixOps4 eventually - }; - } - ); - - peertube-configuration = makeConfigurationResource peertubeConfigurationResource ( - { pkgs, ... }: - mkIf panelConfig.peertube.enable { - fediversity = { - inherit (panelConfig) domain; - temp.initialUser = { - inherit (panelConfig.initialUser) username email displayName; - # FIXME: disgusting, but nvm, this is going to be replaced by - # proper central authentication at some point - passwordFile = pkgs.writeText "password" panelConfig.initialUser.password; - }; - - peertube = peertubeS3KeyConfig { inherit pkgs; } // { - enable = true; - ## NOTE: Only ever used for testing anyway. - ## - ## FIXME: Generate and store in NixOps4's state. - secretsFile = pkgs.writeText "secret" "574e093907d1157ac0f8e760a6deb1035402003af5763135bae9cbd6abe32b24"; - }; - }; - } - ); - - pixelfed-configuration = makeConfigurationResource pixelfedConfigurationResource ( - { pkgs, ... }: - mkIf panelConfig.pixelfed.enable { - fediversity = { - inherit (panelConfig) domain; - temp.initialUser = { - inherit (panelConfig.initialUser) username email displayName; - # FIXME: disgusting, but nvm, this is going to be replaced by - # proper central authentication at some point - passwordFile = pkgs.writeText "password" panelConfig.initialUser.password; - }; - - pixelfed = pixelfedS3KeyConfig { inherit pkgs; } // { - enable = true; - }; - }; - } - ); + config = { + deployment = deployment-configuration; + #// { + # TODO(@fricklerhandwerk): + # the Clan JSON schema converter always marks "object" types as optional, + # which means we need to deal with that *somewhere*, and as a hack it's done here. + # right now, since initial form contents are produced from Pydantic default values, we get None for those nested objects, which translates to `null` here. + #mastodon = optionalAttrs (isNull deployment-configuration.mastodon) { }; + #peertube = optionalAttrs (isNull deployment-configuration.peertube) { }; + #pixelfed = optionalAttrs (isNull deployment-configuration.pixelfed) { }; + #}; + providers = { + inherit (nixops4.modules.nixops4Provider) local; }; + + resources = + let + ## NOTE: All of these secrets are publicly available in this source file + ## and will end up in the Nix store. We don't care as they are only ever + ## used for testing anyway. + ## + ## FIXME: Generate and store in NixOps4's state. + mastodonS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK3515373e4c851ebaad366558"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34"; + }; + peertubeS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK1f9feea9960f6f95ff404c9b"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395"; + }; + pixelfedS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GKb5615457d44214411e673b7b"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "5be6799a88ca9b9d813d1a806b64f15efa49482dbe15339ddfaf7f19cf434987"; + }; + + makeConfigurationResource = resourceModule: deployment-configuration: { + type = providers.local.exec; + imports = [ + nixops4-nixos.modules.nixops4Resource.nixos + resourceModule + + { + ## NOTE: With NixOps4, there are several levels and all of them live + ## in the NixOS module system: + ## + ## 1. Each NixOps4 deployment is a module. + ## 2. Each NixOps4 resource is a module. This very comment is + ## inside an attrset imported as a module in a resource. + ## 3. Each NixOps4 'configuration' resource contains an attribute + ## 'nixos.module', itself a NixOS configuration module. + nixos.module = + { ... }: + { + imports = [ + deployment-configuration + fediversity + ]; + }; + } + ]; + }; + + in + + { + garage-configuration = makeConfigurationResource garageConfigurationResource ( + { pkgs, ... }: + mkIf (panelConfig.mastodon.enable || panelConfig.peertube.enable || panelConfig.pixelfed.enable) { + fediversity = { + inherit (panelConfig) domain; + garage.enable = true; + pixelfed = pixelfedS3KeyConfig { inherit pkgs; }; + mastodon = mastodonS3KeyConfig { inherit pkgs; }; + peertube = peertubeS3KeyConfig { inherit pkgs; }; + }; + } + ); + + mastodon-configuration = makeConfigurationResource mastodonConfigurationResource ( + { pkgs, ... }: + mkIf panelConfig.mastodon.enable { + fediversity = { + inherit (panelConfig) domain; + temp.initialUser = { + inherit (panelConfig.initialUser) username email displayName; + # FIXME: disgusting, but nvm, this is going to be replaced by + # proper central authentication at some point + passwordFile = pkgs.writeText "password" panelConfig.initialUser.password; + }; + + mastodon = mastodonS3KeyConfig { inherit pkgs; } // { + enable = true; + }; + + temp.cores = 1; # FIXME: should come from NixOps4 eventually + }; + } + ); + + peertube-configuration = makeConfigurationResource peertubeConfigurationResource ( + { pkgs, ... }: + mkIf panelConfig.peertube.enable { + fediversity = { + inherit (panelConfig) domain; + temp.initialUser = { + inherit (panelConfig.initialUser) username email displayName; + # FIXME: disgusting, but nvm, this is going to be replaced by + # proper central authentication at some point + passwordFile = pkgs.writeText "password" panelConfig.initialUser.password; + }; + + peertube = peertubeS3KeyConfig { inherit pkgs; } // { + enable = true; + ## NOTE: Only ever used for testing anyway. + ## + ## FIXME: Generate and store in NixOps4's state. + secretsFile = pkgs.writeText "secret" "574e093907d1157ac0f8e760a6deb1035402003af5763135bae9cbd6abe32b24"; + }; + }; + } + ); + + pixelfed-configuration = makeConfigurationResource pixelfedConfigurationResource ( + { pkgs, ... }: + mkIf panelConfig.pixelfed.enable { + fediversity = { + inherit (panelConfig) domain; + temp.initialUser = { + inherit (panelConfig.initialUser) username email displayName; + # FIXME: disgusting, but nvm, this is going to be replaced by + # proper central authentication at some point + passwordFile = pkgs.writeText "password" panelConfig.initialUser.password; + }; + + pixelfed = pixelfedS3KeyConfig { inherit pkgs; } // { + enable = true; + }; + }; + } + ); + }; + }; } diff --git a/panel/src/panel/templates/partials/deployment_result.html b/panel/src/panel/templates/partials/deployment_result.html index 353d93c7..f0803b97 100644 --- a/panel/src/panel/templates/partials/deployment_result.html +++ b/panel/src/panel/templates/partials/deployment_result.html @@ -5,7 +5,7 @@ {% for service_name, service_meta in services.items %} {% if service_meta.enable %}
  • - ✓ {{ service_name }} + ✓ {{ service_name }}
  • {% endif %} {% endfor %} diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 1eb48c6f..f9c89d5c 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -65,6 +65,8 @@ class ConfigurationForm(LoginRequiredMixin, APIView): return Response({'serializer': serializer}) config.value = json.dumps(serializer.validated_data) + print(request.data) + print(config.value) config.save() return redirect(self.success_url)