WIP: simplify deployment code

This commit is contained in:
Valentin Gagarin 2025-03-31 15:44:23 +02:00 committed by Kiara Grouwstra
parent 19b0684ee7
commit 8fbb3b6614
Signed by: kiara
SSH key fingerprint: SHA256:COspvLoLJ5WC5rFb9ZDe5urVCkK4LJZOsjfF4duRJFU
3 changed files with 51 additions and 48 deletions
deployment
panel/src/panel

View file

@ -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";
};
};
};
};
};

View file

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

View file

@ -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