Commit 00df56d1 by Kálmán Viktor

dashboard: disk remove as op view

- disk remove with op view in vm detail
- still use old disk remove for removing disks from template
- also fix some resize code
parent 250c4b3d
...@@ -844,6 +844,35 @@ class VmDiskResizeForm(forms.Form): ...@@ -844,6 +844,35 @@ class VmDiskResizeForm(forms.Form):
return helper return helper
class VmDiskRemoveForm(forms.Form):
def __init__(self, *args, **kwargs):
choices = kwargs.pop('choices')
self.disk = kwargs.pop('default')
super(VmDiskRemoveForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'disk', forms.ModelChoiceField(
queryset=choices, initial=self.disk, required=True,
empty_label=None, label=_('Disk')))
if self.disk:
self.fields['disk'].widget = HiddenInput()
@property
def helper(self):
helper = FormHelper(self)
helper.form_tag = False
if self.disk:
helper.layout = Layout(
AnyTag(
"div",
HTML(_("<label>Disk:</label> %s") % self.disk),
css_class="form-group",
),
Field("disk"),
)
return helper
class VmDownloadDiskForm(forms.Form): class VmDownloadDiskForm(forms.Form):
name = forms.CharField(max_length=100, label=_("Name")) name = forms.CharField(max_length=100, label=_("Name"))
url = forms.CharField(label=_('URL'), validators=[URLValidator(), ]) url = forms.CharField(label=_('URL'), validators=[URLValidator(), ])
......
{% load i18n %} {% load i18n %}
{% load sizefieldtags %} {% load sizefieldtags %}
<i class="fa {% if d.is_downloading %}fa-refresh fa-spin{% else %}fa-file{% if d.failed %}" style="color: #d9534f;{% endif %}{% endif %}"></i> <i class="fa fa-file"></i>
{{ d.name }} (#{{ d.id }}) - {{ d.name }} (#{{ d.id }})
{% if not d.is_downloading %}
{% if not d.failed %} {% if op.remove_disk %}
{% if d.size %}{{ d.size|filesize }}{% endif %} <span class="operation-wrapper">
{% else %} <a href="{{ op.remove_disk.get_url }}?disk={{d.pk}}"
<div class="label label-danger"{% if user.is_superuser %} title="{{ d.get_latest_activity_result }}"{% endif %}>{% trans "failed" %}</div> class="btn btn-xs btn-{{ op.remove_disk.effect}} pull-right operation disk-remove-btn
{% endif %} {% if op.resize_disk.disabled %}disabled{% endif %}">
{% else %}<span class="disk-list-disk-percentage" data-disk-pk="{{ d.pk }}">{{ d.get_download_percentage }}</span>%{% endif %} <i class="fa fa-{{ op.remove_disk.icon }}"></i> {% trans "Remove" %}
{% if is_owner != False %}
<a href="{% url "dashboard.views.disk-remove" pk=d.pk %}?next={{ request.path }}"
data-disk-pk="{{ d.pk }}" class="btn btn-xs btn-danger pull-right disk-remove"
{% if not long_remove %}title="{% trans "Remove" %}"{% endif %}>
<i class="fa fa-times"></i>{% if long_remove %} {% trans "Remove" %}{% endif %}
</a> </a>
{% if op.resize_disk %} </span>
{% endif %}
{% if op.resize_disk %}
<span class="operation-wrapper"> <span class="operation-wrapper">
<a href="{{ op.resize_disk.get_url }}?disk={{d.pk}}" <a href="{{ op.resize_disk.get_url }}?disk={{d.pk}}"
class="btn btn-xs btn-warning pull-right operation disk-resize-btn"> class="btn btn-xs btn-{{ op.resize_disk.effect }} pull-right operation disk-resize-btn
<i class="fa fa-arrows-alt"></i> {% trans "Resize" %} {% if op.resize_disk.disabled %}disabled{% endif %}">
<i class="fa fa-{{ op.resize_disk.icon }}"></i> {% trans "Resize" %}
</a> </a>
</span> </span>
{% endif %}
{% endif %} {% endif %}
<div style="clear: both;"></div> <div style="clear: both;"></div>
...@@ -86,7 +86,13 @@ ...@@ -86,7 +86,13 @@
{% endif %} {% endif %}
{% for d in disks %} {% for d in disks %}
<li> <li>
{% include "dashboard/_disk-list-element.html" %} <i class="fa fa-file"></i>
{{ d.name }} (#{{ d.id }}) -
<a href="{% url "dashboard.views.disk-remove" pk=d.pk %}?next={{ request.path }}"
data-disk-pk="{{ d.pk }}" class="btn btn-xs btn-danger pull-right disk-remove"
{% if not long_remove %}title="{% trans "Remove" %}"{% endif %}>
<i class="fa fa-times"></i>{% if long_remove %} {% trans "Remove" %}{% endif %}
</a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
......
...@@ -37,6 +37,7 @@ from braces.views import ( ...@@ -37,6 +37,7 @@ from braces.views import (
from django_tables2 import SingleTableView from django_tables2 import SingleTableView
from vm.models import InstanceTemplate, InterfaceTemplate, Instance, Lease from vm.models import InstanceTemplate, InterfaceTemplate, Instance, Lease
from storage.models import Disk
from ..forms import ( from ..forms import (
TemplateForm, TemplateListSearchForm, AclUserOrGroupAddForm, LeaseForm, TemplateForm, TemplateListSearchForm, AclUserOrGroupAddForm, LeaseForm,
...@@ -319,6 +320,51 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView): ...@@ -319,6 +320,51 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
return kwargs return kwargs
class DiskRemoveView(DeleteView):
model = Disk
def get_template_names(self):
if self.request.is_ajax():
return ['dashboard/confirm/ajax-delete.html']
else:
return ['dashboard/confirm/base-delete.html']
def get_context_data(self, **kwargs):
context = super(DiskRemoveView, self).get_context_data(**kwargs)
disk = self.get_object()
app = disk.get_appliance()
context['title'] = _("Disk remove confirmation")
context['text'] = _("Are you sure you want to remove "
"<strong>%(disk)s</strong> from "
"<strong>%(app)s</strong>?" % {'disk': disk,
'app': app}
)
return context
def delete(self, request, *args, **kwargs):
disk = self.get_object()
app = disk.get_appliance()
if not app.has_level(request.user, 'owner'):
raise PermissionDenied()
app.remove_disk(disk=disk, user=request.user)
disk.destroy()
next_url = request.POST.get("next")
success_url = next_url if next_url else app.get_absolute_url()
success_message = _("Disk successfully removed.")
if request.is_ajax():
return HttpResponse(
json.dumps({'message': success_message}),
content_type="application/json",
)
else:
messages.success(request, success_message)
return HttpResponseRedirect("%s#resources" % success_url)
class LeaseCreate(LoginRequiredMixin, PermissionRequiredMixin, class LeaseCreate(LoginRequiredMixin, PermissionRequiredMixin,
SuccessMessageMixin, CreateView): SuccessMessageMixin, CreateView):
model = Lease model = Lease
......
...@@ -58,7 +58,7 @@ from ..forms import ( ...@@ -58,7 +58,7 @@ from ..forms import (
AclUserOrGroupAddForm, VmResourcesForm, TraitsForm, RawDataForm, AclUserOrGroupAddForm, VmResourcesForm, TraitsForm, RawDataForm,
VmAddInterfaceForm, VmCreateDiskForm, VmDownloadDiskForm, VmSaveForm, VmAddInterfaceForm, VmCreateDiskForm, VmDownloadDiskForm, VmSaveForm,
VmRenewForm, VmStateChangeForm, VmListSearchForm, VmCustomizeForm, VmRenewForm, VmStateChangeForm, VmListSearchForm, VmCustomizeForm,
TransferOwnershipForm, VmDiskResizeForm, RedeployForm, TransferOwnershipForm, VmDiskResizeForm, RedeployForm, VmDiskRemoveForm,
) )
from ..models import Favourite, Profile from ..models import Favourite, Profile
...@@ -375,7 +375,7 @@ class VmDiskResizeView(FormOperationMixin, VmOperationView): ...@@ -375,7 +375,7 @@ class VmDiskResizeView(FormOperationMixin, VmOperationView):
form_class = VmDiskResizeForm form_class = VmDiskResizeForm
show_in_toolbar = False show_in_toolbar = False
icon = 'arrows-alt' icon = 'arrows-alt'
effect = "success" effect = "warning"
def get_form_kwargs(self): def get_form_kwargs(self):
choices = self.get_op().instance.disks choices = self.get_op().instance.disks
...@@ -393,6 +393,30 @@ class VmDiskResizeView(FormOperationMixin, VmOperationView): ...@@ -393,6 +393,30 @@ class VmDiskResizeView(FormOperationMixin, VmOperationView):
return val return val
class VmDiskRemoveView(FormOperationMixin, VmOperationView):
op = 'remove_disk'
form_class = VmDiskRemoveForm
show_in_toolbar = False
icon = "times"
effect = "danger"
def get_form_kwargs(self):
choices = self.get_op().instance.disks
disk_pk = self.request.GET.get('disk')
if disk_pk:
try:
default = choices.get(pk=disk_pk)
except (ValueError, Disk.DoesNotExist):
raise Http404()
else:
default = None
val = super(VmDiskRemoveView, self).get_form_kwargs()
val.update({'choices': choices, 'default': default})
return val
class VmCreateDiskView(FormOperationMixin, VmOperationView): class VmCreateDiskView(FormOperationMixin, VmOperationView):
op = 'create_disk' op = 'create_disk'
...@@ -640,6 +664,7 @@ vm_ops = OrderedDict([ ...@@ -640,6 +664,7 @@ vm_ops = OrderedDict([
('create_disk', VmCreateDiskView), ('create_disk', VmCreateDiskView),
('download_disk', VmDownloadDiskView), ('download_disk', VmDownloadDiskView),
('resize_disk', VmDiskResizeView), ('resize_disk', VmDiskResizeView),
('remove_disk', VmDiskRemoveView),
('add_interface', VmAddInterfaceView), ('add_interface', VmAddInterfaceView),
('renew', VmRenewView), ('renew', VmRenewView),
('resources_change', VmResourcesChangeView), ('resources_change', VmResourcesChangeView),
...@@ -1103,51 +1128,6 @@ class InstanceActivityDetail(CheckedDetailView): ...@@ -1103,51 +1128,6 @@ class InstanceActivityDetail(CheckedDetailView):
return ctx return ctx
class DiskRemoveView(DeleteView):
model = Disk
def get_template_names(self):
if self.request.is_ajax():
return ['dashboard/confirm/ajax-delete.html']
else:
return ['dashboard/confirm/base-delete.html']
def get_context_data(self, **kwargs):
context = super(DiskRemoveView, self).get_context_data(**kwargs)
disk = self.get_object()
app = disk.get_appliance()
context['title'] = _("Disk remove confirmation")
context['text'] = _("Are you sure you want to remove "
"<strong>%(disk)s</strong> from "
"<strong>%(app)s</strong>?" % {'disk': disk,
'app': app}
)
return context
def delete(self, request, *args, **kwargs):
disk = self.get_object()
app = disk.get_appliance()
if not app.has_level(request.user, 'owner'):
raise PermissionDenied()
app.remove_disk(disk=disk, user=request.user)
disk.destroy()
next_url = request.POST.get("next")
success_url = next_url if next_url else app.get_absolute_url()
success_message = _("Disk successfully removed.")
if request.is_ajax():
return HttpResponse(
json.dumps({'message': success_message}),
content_type="application/json",
)
else:
messages.success(request, success_message)
return HttpResponseRedirect("%s#resources" % success_url)
@require_GET @require_GET
def get_disk_download_status(request, pk): def get_disk_download_status(request, pk):
disk = Disk.objects.get(pk=pk) disk = Disk.objects.get(pk=pk)
......
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