diff --git a/deployment/options.nix b/deployment/options.nix
index df04b994..27d38bce 100644
--- a/deployment/options.nix
+++ b/deployment/options.nix
@@ -2,7 +2,7 @@
Deployment options as to be presented in the front end.
These are converted to JSON schema in order to generate front-end forms etc.
- For this to work, options must not have types `functionTo` or `package` (or `submodule` until [submodule introspection](https://github.com/NixOS/nixpkgs/pull/391544) is merged), and must not access `config` for their default values.
+ For this to work, options must not have types `functionTo` or `package`, and must not access `config` for their default values.
*/
{
lib,
@@ -34,22 +34,30 @@ in
mastodon = {
enable = lib.mkEnableOption "Mastodon";
};
- initialUser = {
- displayName = mkOption {
- type = types.str;
- description = "Display name of the user";
- };
- username = mkOption {
- type = types.str;
- description = "Username for login";
- };
- email = mkOption {
- type = types.str;
- description = "User's email address";
- };
- password = mkOption {
- type = types.str;
- description = "Password for login";
+ initialUser = mkOption {
+ description = ''
+ Some services require an initial user to access them.
+ This option sets the credentials for such an initial user.
+ '';
+ type = types.submodule {
+ options = {
+ displayName = mkOption {
+ type = types.str;
+ description = "Display name of the user";
+ };
+ username = mkOption {
+ type = types.str;
+ description = "Username for login";
+ };
+ email = mkOption {
+ type = types.str;
+ description = "User's email address";
+ };
+ password = mkOption {
+ type = types.str;
+ description = "Password for login";
+ };
+ };
};
};
};
diff --git a/panel/src/panel/templates/partials/deployment_result.html b/panel/src/panel/templates/partials/deployment_result.html
index d342ad18..353d93c7 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 29eb31d9..1eb48c6f 100644
--- a/panel/src/panel/views.py
+++ b/panel/src/panel/views.py
@@ -14,6 +14,8 @@ from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
+from pydantic import BaseModel
+
from panel import models, settings
from panel.configuration import schema
@@ -39,7 +41,6 @@ class ConfigurationForm(LoginRequiredMixin, APIView):
success_url = reverse_lazy('configuration_form')
def get_object(self):
- """Get or create the configuration object for the current user"""
obj, created = models.Configuration.objects.get_or_create(
operator=self.request.user,
)
@@ -67,37 +68,33 @@ class ConfigurationForm(LoginRequiredMixin, APIView):
config.save()
return redirect(self.success_url)
+# TODO(@fricklerhandwerk):
+# this is broken after changing the form view.
+# but if there's no test for it, how do we know it ever worked in the first place?
class DeploymentStatus(ConfigurationForm):
- def form_valid(self, form):
- obj = self.get_object()
- obj.value = form.to_python().model_dump_json()
- obj.save()
- # Check for deploy button
- if "deploy" in self.request.POST.keys():
- deployment_result, deployment_params = self.deployment(obj)
- deployment_succeeded = deployment_result.returncode == 0
+ def post(self, request):
+ config = self.get_object()
+ serializer = schema.Model.drf_serializer(
+ instance=config.parsed_value,
+ data=request.data
+ )
+
+ if not serializer.is_valid():
+ return Response({'serializer': serializer})
+
+ config.value = json.dumps(serializer.validated_data)
+ config.save()
+
+ deployment_result, deployment_params = self.deployment(config.parsed_value)
+ deployment_succeeded = deployment_result.returncode == 0
return render(self.request, "partials/deployment_result.html", {
"deployment_succeeded": deployment_succeeded,
- "services": {
- "peertube": {
- "enable": deployment_params['peertube']['enable'],
- "url": f"https://peertube.{deployment_params['domain']}",
- },
- "pixelfed":{
- "enable": deployment_params['pixelfed']['enable'],
- "url": f"https://pixelfed.{deployment_params['domain']}",
- },
- "mastodon": {
- "enable": deployment_params['mastodon']['enable'],
- "url": f"https://mastodon.{deployment_params['domain']}",
- },
- },
- })
+ "services": deployment_params.json(),
+ })
- def deployment(self, obj):
- submission = obj.parsed_value.model_dump_json()
+ def deployment(self, config: BaseModel):
# FIXME: let the user specify these from the form (#190)
dummy_user = {
"initialUser": {
@@ -107,12 +104,10 @@ class DeploymentStatus(ConfigurationForm):
"email": "test@test.com",
},
}
- # serialize back and forth now we still need to manually inject the dummy user
- deployment_params = json.dumps(dummy_user | json.loads(submission))
env = {
"PATH": settings.bin_path,
# pass in form info to our deployment
- "DEPLOYMENT": deployment_params,
+ "DEPLOYMENT": config.json()
}
cmd = [
"nix",
@@ -129,4 +124,4 @@ class DeploymentStatus(ConfigurationForm):
cwd=settings.repo_dir,
env=env,
)
- return deployment_result, json.loads(deployment_params)
+ return deployment_result, config