Commit 7507ef24 by Szabolcs Gelencsér

Implement vm resize on VmDetails

parent 395bd172
...@@ -1472,41 +1472,19 @@ class GroupPermissionForm(forms.ModelForm): ...@@ -1472,41 +1472,19 @@ class GroupPermissionForm(forms.ModelForm):
return helper return helper
class VmResourcesForm(forms.ModelForm): class VmResourcesForm(forms.Form):
num_cores = forms.IntegerField(widget=forms.NumberInput(attrs={ flavor = forms.ChoiceField([], widget=forms.Select(attrs={
'class': "form-control input-tags cpu-count-input", 'class': "form-control input-tags",
'min': 1,
'max': 10,
'required': "",
}),
min_value=1, max_value=10,
)
ram_size = forms.IntegerField(widget=forms.NumberInput(attrs={
'class': "form-control input-tags ram-input",
'min': 128,
'max': MAX_NODE_RAM,
'step': 128,
'required': "",
}),
min_value=128, max_value=MAX_NODE_RAM,
)
priority = forms.ChoiceField(priority_choices, widget=forms.Select(attrs={
'class': "form-control input-tags cpu-priority-input",
})) }))
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.can_edit = kwargs.pop("can_edit", None) self.instance = kwargs.pop("instance", None)
super(VmResourcesForm, self).__init__(*args, **kwargs) self.flavors = kwargs.pop("flavors", None)
if not self.can_edit: super(VmResourcesForm, self).__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs['disabled'] = "disabled"
class Meta: self.fields['flavor'].choices = ((f.id, f.name) for f in self.flavors)
model = Instance self.fields['flavor'].initial = self.instance.flavor['id']
fields = ('num_cores', 'priority', 'ram_size', )
class VmRenameForm(forms.Form): class VmRenameForm(forms.Form):
......
...@@ -8,37 +8,13 @@ ...@@ -8,37 +8,13 @@
</div> </div>
<form method="POST" action="{{ op.resources_change.get_url }}" id="vm-details-resources-form"> <form method="POST" action="{{ op.resources_change.get_url }}" id="vm-details-resources-form">
{% csrf_token %} {% csrf_token %}
{% include "dashboard/_resources-sliders.html" with field_priority=resources_form.priority field_num_cores=resources_form.num_cores field_ram_size=resources_form.ram_size %}
{% if op.resources_change %} {{ resources_form.flavor|as_crispy_field }}
<button type="submit" class="btn btn-success btn-sm change-resources-button" <button type="submit" class="btn btn-success btn-sm change-resources-button"
id="vm-details-resources-save" data-vm="{{ instance.pk }}" id="vm-details-resources-save" data-vm="{{ instance.pk }}">
{% if not save_resources_enabled %}disabled{% endif %}>
<i class="fa fa-floppy-o"></i> {% trans "Save resources" %} <i class="fa fa-floppy-o"></i> {% trans "Save resources" %}
</button> </button>
<span class="change-resources-help"
{% if save_resources_enabled %}style="display: none;"{% endif %}>
{% trans "Stop your VM to change resources." %}
</span>
{% else %}
<div id="vm-request-resource-form">
<div class="alert alert-info text-justify">
{% trans "Changing resources is only possible on virtual machines with STOPPED state. We suggest to turn off the VM after submitting the request otherwise it will be automatically stopped in the future when the request is accepted." %}
</div>
<div class="form-group">
<label>{% trans "Message" %}*</label>
<textarea class="form-control" name="message">{% include "request/initials/resources.html" %}</textarea>
</div>
<input type="submit" class="btn btn-success btn-sm"/>
</div>
<a href="{% url "request.views.request-resource" vm_pk=object.id %}"
class="btn btn-primary btn-sm" id="vm-request-resource">
<i class="fa fa-tasks"></i>
{% trans "Request resources" %}
</a>
{% endif %}
</form> </form>
<hr /> <hr />
......
...@@ -220,9 +220,8 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView): ...@@ -220,9 +220,8 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
# context['traits_form'] = TraitsForm(instance=instance) # context['traits_form'] = TraitsForm(instance=instance)
# context['raw_data_form'] = RawDataForm(instance=instance) # context['raw_data_form'] = RawDataForm(instance=instance)
# resources change perm context['resources_form'] = VmResourcesForm(instance=instance,
context['can_change_resources'] = self.request.user.has_perm( flavors=openstack_api.nova.flavor_list(self.request))
"vm.change_resources")
# client info # client info
context['client_download'] = self.request.COOKIES.get( context['client_download'] = self.request.COOKIES.get(
...@@ -230,12 +229,6 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView): ...@@ -230,12 +229,6 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
# can link template # can link template
# context['can_link_template'] = instance.template # context['can_link_template'] = instance.template
# operation also allows RUNNING (if with_shutdown is present)
context['save_resources_enabled'] = instance.status in (
"STOPPED",
"PENDING",
)
return context return context
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
...@@ -605,39 +598,15 @@ class VmSaveView(FormOperationMixin, VmOperationView): ...@@ -605,39 +598,15 @@ class VmSaveView(FormOperationMixin, VmOperationView):
return context return context
# class VmResourcesChangeView(VmOperationView): class VmResourcesChangeView(VmOperationView):
# op = 'resources_change' op = 'resources_change'
# icon = "save" icon = "save"
# show_in_toolbar = False show_in_toolbar = False
# wait_for_result = 0.5
# def post(self, request, *args, **kwargs):
# def post(self, request, extra=None, *args, **kwargs): return super(VmResourcesChangeView, self).post(request, {"flavor": request.POST['flavor']})
# if extra is None:
# extra = {}
#
# instance = get_object_or_404(Instance, pk=kwargs['pk'])
#
# form = VmResourcesForm(request.POST, instance=instance)
# if not form.is_valid():
# for f in form.errors:
# messages.error(request, "<strong>%s</strong>: %s" % (
# f, form.errors[f].as_text()
# ))
# if request.is_ajax(): # this is not too nice
# store = messages.get_messages(request)
# store.used = True
# return JsonResponse({'success': False,
# 'messages': [unicode(m) for m in store]})
# else:
# return HttpResponseRedirect(instance.get_absolute_url() +
# "#resources")
# else:
# extra = form.cleaned_data
# extra['max_ram_size'] = extra['ram_size']
# return super(VmResourcesChangeView, self).post(request, extra,
# *args, **kwargs)
#
#
# class TokenOperationView(OperationView): # class TokenOperationView(OperationView):
# """Abstract operation view with token support. # """Abstract operation view with token support.
# #
...@@ -862,7 +831,7 @@ vm_ops = OrderedDict([ ...@@ -862,7 +831,7 @@ vm_ops = OrderedDict([
('add_public_ip', VmPublicIpAddView), ('add_public_ip', VmPublicIpAddView),
('remove_public_ip', VmPublicIpRemoveView), ('remove_public_ip', VmPublicIpRemoveView),
('renew', VmRenewView), ('renew', VmRenewView),
# ('resources_change', VmResourcesChangeView), ('resources_change', VmResourcesChangeView),
# ('password_reset', VmOperationView.factory( # ('password_reset', VmOperationView.factory(
# op='password_reset', icon='unlock', effect='warning', # op='password_reset', icon='unlock', effect='warning',
# show_in_toolbar=False, wait_for_result=0.5, with_reload=True)), # show_in_toolbar=False, wait_for_result=0.5, with_reload=True)),
......
...@@ -1043,36 +1043,13 @@ class ResourcesOperation(InstanceOperation): ...@@ -1043,36 +1043,13 @@ class ResourcesOperation(InstanceOperation):
id = 'resources_change' id = 'resources_change'
name = _("resources change") name = _("resources change")
description = _("Change resources of a stopped virtual machine.") description = _("Change resources of a stopped virtual machine.")
acl_level = "owner"
required_perms = ('vm.change_resources',)
accept_states = ('STOPPED', 'PENDING', 'ACTIVE') accept_states = ('STOPPED', 'PENDING', 'ACTIVE')
os_policy_actions = (("compute", "compute:resize"),)
def _operation(self, user, activity, def _operation(self, request, flavor):
num_cores, ram_size, max_ram_size, priority, openstack_api.nova.server_resize(request, self.instance.id, flavor)
with_shutdown=False, task=None): openstack_api.nova.server_confirm_resize(request, self.instance.id)
if self.instance.status == 'ACTIVE' and not with_shutdown: return create_readable(ugettext_noop("Flavor changed"))
raise Instance.WrongStateError(self.instance)
try:
self.instance.shutdown(parent_activity=activity, task=task)
except Instance.WrongStateError:
pass
self.instance._update_status()
self.instance.num_cores = num_cores
self.instance.ram_size = ram_size
self.instance.max_ram_size = max_ram_size
self.instance.priority = priority
self.instance.full_clean()
self.instance.save()
return create_readable(ugettext_noop(
"Priority: %(priority)s, Num cores: %(num_cores)s, "
"Ram size: %(ram_size)s"), priority=priority, num_cores=num_cores,
ram_size=ram_size
)
@register_operation @register_operation
......
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 sign in to comment