Commit 88a62c53 authored by BAIRE Anthony's avatar BAIRE Anthony
Browse files

fix setting Webapp.memory_limit in the UI


- add config key ALLGO_WEBAPP_DEFAULT_MEMORY_LIMIT_MB to set the
  default memory limit for newly created webapps

- add memory limit field in WebappUpdate

- display memory_limit in megabytes in the UI (through the
  memory_limit_mb form field)

- disable the memory_limit_mb widget and ignored the posted value
  when user is not superuser

- forbid negative value in the model

- make the memory limit field required in the forms
parent b2d1a33b
Pipeline #40211 failed with stage
in 1 minute and 19 seconds
......@@ -4,6 +4,7 @@ from django.contrib.auth.models import User
from django.core.validators import RegexValidator
from taggit.forms import TagField
import config
from .models import (
AllgoUser,
DockerOs,
......@@ -56,11 +57,24 @@ class UserWebappForm(forms.ModelForm):
notebook_gitrepo = forms.URLField(required=False, label="Notebook repository", label_suffix="")
owner = forms.CharField(required=False, label="Owner", label_suffix='')
tags = TagField(label_suffix='')
memory_limit_mb = forms.IntegerField(label="Memory limit", label_suffix='',
min_value=0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
webapp = Webapp.objects.get(docker_name=self.instance.docker_name)
self.fields['owner'].initial = self.instance.user
self.fields['memory_limit_mb'].initial = (
self.instance.memory_limit // 1024**2
or config.env.ALLGO_WEBAPP_DEFAULT_MEMORY_LIMIT_MB)
def get_memory_limit(self, request):
# only allgo admins are allowed to change the memory limit
if request.user.is_superuser:
# value is converted into bytes
return self.cleaned_data["memory_limit_mb"] * 1024**2
else:
return self.instance.memory_limit
class Meta:
model = Webapp
......@@ -158,7 +172,9 @@ class WebappForm(forms.ModelForm):
initial=1,
label='Operating sytem',
label_suffix='')
memory_limit = forms.IntegerField(label="Memory limit", label_suffix='', required=False)
memory_limit_mb = forms.IntegerField(label="Memory limit", label_suffix='',
initial=config.env.ALLGO_WEBAPP_DEFAULT_MEMORY_LIMIT_MB,
min_value=0)
job_queue = forms.ModelChoiceField(
queryset=JobQueue.objects.all().distinct(),
initial=1,
......@@ -172,10 +188,17 @@ class WebappForm(forms.ModelForm):
field.error_messages = {'required':'The field "{fieldname}" is required'.format(
fieldname=field.label)}
def get_memory_limit(self, request):
# - only allgo admins are allowed to set an arbitrary limit
# - value is converted into bytes
return (self.cleaned_data["memory_limit_mb"]
if request.user.is_superuser
else config.env.ALLGO_WEBAPP_DEFAULT_MEMORY_LIMIT_MB
) * 1024**2
class Meta:
model = Webapp
fields = ('name', 'description', 'logo_file_name', 'contact', 'entrypoint', 'job_queue', 'private', 'memory_limit', 'docker_os')
fields = ('name', 'description', 'logo_file_name', 'contact', 'entrypoint', 'job_queue', 'private', 'docker_os')
class WebappSandboxForm(forms.ModelForm):
......
......@@ -171,7 +171,8 @@ class Webapp(TimeStampModel):
sandbox_version = models.ForeignKey('WebappVersion', null=True, blank=True, related_name='webappversions')
notebook_gitrepo = models.CharField(max_length=255, blank=True, null=True)
memory_limit = models.BigIntegerField(blank=True, null=True)
memory_limit = models.BigIntegerField(null=True,
validators=[MinValueValidator(0)])
# Relationships
......
......@@ -190,12 +190,19 @@ class WebappUpdate(SuccessMessageMixin, LoginRequiredMixin, UpdateView):
queryset = get_object_or_404(Webapp, docker_name=data, user_id=self.request.user.id)
return queryset
def get_form(self):
form = super().get_form()
if not self.request.user.is_superuser:
form.fields['memory_limit_mb'].widget.attrs['readonly'] = True
return form
def form_valid(self, form):
"""Save data coming from the form in the database """
obj = form.save(commit=False)
try:
user = User.objects.get(username=form.cleaned_data['owner'])
obj.user_id = user.id
obj.memory_limit = form.get_memory_limit(self.request)
form.save()
# Add the tag to the database (specific because it's a many to
# many relationship)
......@@ -231,6 +238,12 @@ class WebappCreate(SuccessMessageMixin, LoginRequiredMixin, GroupRequiredMixin,
"""If successful redirect to the webapp list page"""
return reverse('main:webapp_sandbox_panel', args=(self.webapp.docker_name,))
def get_form(self):
form = super().get_form()
if not self.request.user.is_superuser:
form.fields['memory_limit_mb'].widget.attrs['readonly'] = True
return form
def form_valid(self, form):
"""Save data coming from the form in the database """
obj = form.save(commit=False)
......@@ -241,6 +254,7 @@ class WebappCreate(SuccessMessageMixin, LoginRequiredMixin, GroupRequiredMixin,
# Ensure that all specials characters are removed, spaces are replaced
# by hyphens and everything is lower-cased
obj.docker_name = slugify(form.cleaned_data['name'])
obj.memory_limit = form.get_memory_limit(self.request)
# validate the Webapp record before saving
# (this is a safety measure, do not remove)
......
......@@ -79,11 +79,11 @@
</div>
<div class="form-group col">
{{ form.memory_limit.label_tag }}
{{ form.memory_limit_mb.label_tag }}
<div class="input-group">
{{ form.memory_limit | attr:"placeholder:Memory limit" | add_class:"form-control" }}
{{ form.memory_limit_mb | attr:"placeholder:Memory limit" | add_class:"form-control" }}
<div class="input-group-append">
<span class="input-group-text">GB</span>
<span class="input-group-text">MB</span>
</div>
</div>
</div>
......
......@@ -83,6 +83,16 @@
{{ form.tags | attr:"placeholder:comma, serparated, tags" | add_class:"form-control" }}
</div>
<div class="form-group">
{{ form.memory_limit_mb.label_tag }}
<div class="input-group">
{{ form.memory_limit_mb | attr:"placeholder:Memory limit" | add_class:"form-control" }}
<div class="input-group-append">
<span class="input-group-text">MB</span>
</div>
</div>
</div>
<input class="btn btn-primary" type="submit" value="Update">
</form>
</div>
......
......@@ -180,6 +180,10 @@ with env_loader.EnvironmentVarLoader(__name__, "ALLGO_",
env_var("ALLGO_SSH_PORT", default="2222",
help="tcp port where allgo is reachable by ssh")
env_var("ALLGO_WEBAPP_DEFAULT_MEMORY_LIMIT_MB", default=str(4*1024),
help="default memory limit (in megabytes) for newly created webapps")
#
# allgo authentication tokens
#
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment