generate-module-options-rebase #1

Closed
kiara wants to merge 10 commits from generate-module-options-rebase into generate-module-options
3 changed files with 51 additions and 48 deletions
Showing only changes of commit 8fbb3b6614 - Show all commits

View file

@ -2,7 +2,7 @@
Deployment options as to be presented in the front end. Deployment options as to be presented in the front end.
These are converted to JSON schema in order to generate front-end forms etc. 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, lib,
@ -34,22 +34,30 @@ in
mastodon = { mastodon = {
enable = lib.mkEnableOption "Mastodon"; enable = lib.mkEnableOption "Mastodon";
}; };
initialUser = { initialUser = mkOption {
displayName = mkOption { description = ''
type = types.str; Some services require an initial user to access them.
description = "Display name of the user"; This option sets the credentials for such an initial user.
}; '';
username = mkOption { type = types.submodule {
type = types.str; options = {
description = "Username for login"; displayName = mkOption {
}; type = types.str;
email = mkOption { description = "Display name of the user";
type = types.str; };
description = "User's email address"; username = mkOption {
}; type = types.str;
password = mkOption { description = "Username for login";
type = types.str; };
description = "Password for login"; email = mkOption {
type = types.str;
description = "User's email address";
};
password = mkOption {
type = types.str;
description = "Password for login";
};
};
}; };
}; };
}; };

View file

@ -5,7 +5,7 @@
{% for service_name, service_meta in services.items %} {% for service_name, service_meta in services.items %}
{% if service_meta.enable %} {% if service_meta.enable %}
<li> <li>
<a target="_blank" href={{ service_meta.url }}>{{ service_name }}</a> <a target="_blank" href=https://{{ service_name }}.{{ domain }}>{{ service_name }}</a>
</li> </li>
{% endif %} {% endif %}
{% endfor %} {% endfor %}

View file

@ -14,6 +14,8 @@ from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from pydantic import BaseModel
from panel import models, settings from panel import models, settings
from panel.configuration import schema from panel.configuration import schema
@ -39,7 +41,6 @@ class ConfigurationForm(LoginRequiredMixin, APIView):
success_url = reverse_lazy('configuration_form') success_url = reverse_lazy('configuration_form')
def get_object(self): def get_object(self):
"""Get or create the configuration object for the current user"""
obj, created = models.Configuration.objects.get_or_create( obj, created = models.Configuration.objects.get_or_create(
operator=self.request.user, operator=self.request.user,
) )
@ -67,37 +68,33 @@ class ConfigurationForm(LoginRequiredMixin, APIView):
config.save() config.save()
return redirect(self.success_url) 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): 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 def post(self, request):
if "deploy" in self.request.POST.keys(): config = self.get_object()
deployment_result, deployment_params = self.deployment(obj) serializer = schema.Model.drf_serializer(
deployment_succeeded = deployment_result.returncode == 0 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", { return render(self.request, "partials/deployment_result.html", {
"deployment_succeeded": deployment_succeeded, "deployment_succeeded": deployment_succeeded,
"services": { "services": deployment_params.json(),
"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']}",
},
},
})
def deployment(self, obj): def deployment(self, config: BaseModel):
submission = obj.parsed_value.model_dump_json()
# FIXME: let the user specify these from the form (#190) # FIXME: let the user specify these from the form (#190)
dummy_user = { dummy_user = {
"initialUser": { "initialUser": {
@ -107,12 +104,10 @@ class DeploymentStatus(ConfigurationForm):
"email": "test@test.com", "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 = { env = {
"PATH": settings.bin_path, "PATH": settings.bin_path,
# pass in form info to our deployment # pass in form info to our deployment
"DEPLOYMENT": deployment_params, "DEPLOYMENT": config.json()
} }
cmd = [ cmd = [
"nix", "nix",
@ -129,4 +124,4 @@ class DeploymentStatus(ConfigurationForm):
cwd=settings.repo_dir, cwd=settings.repo_dir,
env=env, env=env,
) )
return deployment_result, json.loads(deployment_params) return deployment_result, config