Commit 7507ef24 by Szabolcs Gelencsér

Implement vm resize on VmDetails

parent 395bd172
......@@ -1472,41 +1472,19 @@ class GroupPermissionForm(forms.ModelForm):
return helper
class VmResourcesForm(forms.ModelForm):
num_cores = forms.IntegerField(widget=forms.NumberInput(attrs={
'class': "form-control input-tags cpu-count-input",
'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",
class VmResourcesForm(forms.Form):
flavor = forms.ChoiceField([], widget=forms.Select(attrs={
'class': "form-control input-tags",
}))
def __init__(self, *args, **kwargs):
self.can_edit = kwargs.pop("can_edit", None)
super(VmResourcesForm, self).__init__(*args, **kwargs)
self.instance = kwargs.pop("instance", None)
self.flavors = kwargs.pop("flavors", None)
if not self.can_edit:
for name, field in self.fields.items():
field.widget.attrs['disabled'] = "disabled"
super(VmResourcesForm, self).__init__(*args, **kwargs)
class Meta:
model = Instance
fields = ('num_cores', 'priority', 'ram_size', )
self.fields['flavor'].choices = ((f.id, f.name) for f in self.flavors)
self.fields['flavor'].initial = self.instance.flavor['id']
class VmRenameForm(forms.Form):
......
......@@ -8,37 +8,13 @@
</div>
<form method="POST" action="{{ op.resources_change.get_url }}" id="vm-details-resources-form">
{% 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"
id="vm-details-resources-save" data-vm="{{ instance.pk }}"
{% if not save_resources_enabled %}disabled{% endif %}>
id="vm-details-resources-save" data-vm="{{ instance.pk }}">
<i class="fa fa-floppy-o"></i> {% trans "Save resources" %}
</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>
<hr />
......
......@@ -220,9 +220,8 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
# context['traits_form'] = TraitsForm(instance=instance)
# context['raw_data_form'] = RawDataForm(instance=instance)
# resources change perm
context['can_change_resources'] = self.request.user.has_perm(
"vm.change_resources")
context['resources_form'] = VmResourcesForm(instance=instance,
flavors=openstack_api.nova.flavor_list(self.request))
# client info
context['client_download'] = self.request.COOKIES.get(
......@@ -230,12 +229,6 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
# can link 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
def post(self, request, *args, **kwargs):
......@@ -605,39 +598,15 @@ class VmSaveView(FormOperationMixin, VmOperationView):
return context
# class VmResourcesChangeView(VmOperationView):
# op = 'resources_change'
# icon = "save"
# show_in_toolbar = False
# wait_for_result = 0.5
#
# def post(self, request, extra=None, *args, **kwargs):
# 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 VmResourcesChangeView(VmOperationView):
op = 'resources_change'
icon = "save"
show_in_toolbar = False
def post(self, request, *args, **kwargs):
return super(VmResourcesChangeView, self).post(request, {"flavor": request.POST['flavor']})
# class TokenOperationView(OperationView):
# """Abstract operation view with token support.
#
......@@ -862,7 +831,7 @@ vm_ops = OrderedDict([
('add_public_ip', VmPublicIpAddView),
('remove_public_ip', VmPublicIpRemoveView),
('renew', VmRenewView),
# ('resources_change', VmResourcesChangeView),
('resources_change', VmResourcesChangeView),
# ('password_reset', VmOperationView.factory(
# op='password_reset', icon='unlock', effect='warning',
# show_in_toolbar=False, wait_for_result=0.5, with_reload=True)),
......
......@@ -1043,36 +1043,13 @@ class ResourcesOperation(InstanceOperation):
id = 'resources_change'
name = _("resources change")
description = _("Change resources of a stopped virtual machine.")
acl_level = "owner"
required_perms = ('vm.change_resources',)
accept_states = ('STOPPED', 'PENDING', 'ACTIVE')
os_policy_actions = (("compute", "compute:resize"),)
def _operation(self, user, activity,
num_cores, ram_size, max_ram_size, priority,
with_shutdown=False, task=None):
if self.instance.status == 'ACTIVE' and not with_shutdown:
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
)
def _operation(self, request, flavor):
openstack_api.nova.server_resize(request, self.instance.id, flavor)
openstack_api.nova.server_confirm_resize(request, self.instance.id)
return create_readable(ugettext_noop("Flavor changed"))
@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