Commit cce7935c by Őry Máté

Merge branch 'feature-opview-retouch' into 'master'

Retouch operation buttons
parents ff62083a b77be59b
......@@ -2,10 +2,20 @@
{% for op in ops %}
{% if op.show_in_toolbar %}
<a href="{{op.get_url}}" class="operation operation-{{op.op}} btn btn-default btn-xs"
title="{{}}: {{op.description}}">
{% if op.disabled %}
<span class="operation operation-{{op.op}} btn btn-{{op.effect}} disabled btn-xs">
{% else %}
<a href="{{op.get_url}}" class="operation operation-{{op.op}} btn
btn-{{op.effect}} btn-xs" title="{{}}: {{op.description}}">
{% endif %}
<i class="icon-{{op.icon}}"></i>
<span class="sr-only">{{}}</span>
<span{% if not op.is_preferred %} class="sr-only"{% endif %}>{{}}</span>
{% if op.disabled %}
{% else %}
{% endif %}
{% endif %}
{% endfor %}
......@@ -17,6 +17,7 @@
from __future__ import unicode_literals, absolute_import
from collections import OrderedDict
from itertools import chain
from os import getenv
import json
......@@ -525,6 +526,7 @@ class OperationView(DetailView):
template_name = 'dashboard/operate.html'
show_in_toolbar = True
effect = None
def name(self):
......@@ -534,6 +536,9 @@ class OperationView(DetailView):
def description(self):
return self.get_op().description
def is_preferred(self):
return self.get_op().is_preferred()
def get_urlname(cls):
return 'dashboard.vm.op.%s' % cls.op
......@@ -583,14 +588,16 @@ class OperationView(DetailView):
return redirect("%s#activity" % self.object.get_absolute_url())
def factory(cls, op, icon='cog'):
def factory(cls, op, icon='cog', effect='info'):
return type(str(cls.__name__ + op),
(cls, ), {'op': op, 'icon': icon})
(cls, ), {'op': op, 'icon': icon, 'effect': effect})
def bind_to_object(cls, instance):
def bind_to_object(cls, instance, **kwargs):
v = cls()
v.get_object = lambda: instance
for key, value in kwargs.iteritems():
setattr(v, key, value)
return v
......@@ -666,6 +673,7 @@ class VmMigrateView(VmOperationView):
op = 'migrate'
icon = 'truck'
effect = 'info'
template_name = 'dashboard/_vm-migrate.html'
def get_context_data(self, **kwargs):
......@@ -688,22 +696,31 @@ class VmSaveView(FormOperationMixin, VmOperationView):
op = 'save_as_template'
icon = 'save'
effect = 'info'
form_class = VmSaveForm
vm_ops = {
'reset': VmOperationView.factory(op='reset', icon='bolt'),
'deploy': VmOperationView.factory(op='deploy', icon='play'),
'migrate': VmMigrateView,
'reboot': VmOperationView.factory(op='reboot', icon='refresh'),
'shut_off': VmOperationView.factory(op='shut_off', icon='ban-circle'),
'shutdown': VmOperationView.factory(op='shutdown', icon='off'),
'save_as_template': VmSaveView,
'destroy': VmOperationView.factory(op='destroy', icon='remove'),
'sleep': VmOperationView.factory(op='sleep', icon='moon'),
'wake_up': VmOperationView.factory(op='wake_up', icon='sun'),
'create_disk': VmCreateDiskView,
'download_disk': VmDownloadDiskView,
vm_ops = OrderedDict([
('deploy', VmOperationView.factory(
op='deploy', icon='play', effect='success')),
('wake_up', VmOperationView.factory(
op='wake_up', icon='sun', effect='success')),
('sleep', VmOperationView.factory(
op='sleep', icon='moon', effect='info')),
('migrate', VmMigrateView),
('save_as_template', VmSaveView),
('reboot', VmOperationView.factory(
op='reboot', icon='refresh', effect='warning')),
('reset', VmOperationView.factory(
op='reset', icon='bolt', effect='warning')),
('shutdown', VmOperationView.factory(
op='shutdown', icon='off', effect='warning')),
('shut_off', VmOperationView.factory(
op='shut_off', icon='ban-circle', effect='warning')),
('destroy', VmOperationView.factory(
op='destroy', icon='remove', effect='danger')),
('create_disk', VmCreateDiskView),
('download_disk', VmDownloadDiskView),
def get_operations(instance, user):
......@@ -713,9 +730,11 @@ def get_operations(instance, user):
op = v.get_op_by_object(instance)
except Exception as e:
except PermissionDenied as e:
logger.debug('Not showing operation %s for %s: %s',
k, instance, unicode(e))
except Exception:
ops.append(v.bind_to_object(instance, disabled=True))
return ops
......@@ -75,6 +75,11 @@ class InstanceOperation(Operation):
code_suffix=self.activity_code_suffix, instance=self.instance,
def is_preferred(self):
"""If this is the recommended op in the current state of the instance.
return False
class AddInterfaceOperation(InstanceOperation):
activity_code_suffix = 'add_interface'
......@@ -154,6 +159,10 @@ class DeployOperation(InstanceOperation):
name = _("deploy")
description = _("Deploy new virtual machine with network.")
def is_preferred(self):
return self.instance.status in (self.instance.STATUS.STOPPED,
def on_commit(self, activity):
activity.resultant_state = 'RUNNING'
......@@ -337,6 +346,10 @@ class SaveAsTemplateOperation(InstanceOperation):
abortable = True
def is_preferred(self):
return (self.instance.is_base and
self.instance.status == self.instance.STATUS.RUNNING)
def _rename(name):
m = search(r" v(\d+)$", name)
......@@ -472,6 +485,10 @@ class SleepOperation(InstanceOperation):
name = _("sleep")
description = _("Suspend virtual machine with memory dump.")
def is_preferred(self):
return (not self.instance.is_base and
self.instance.status == self.instance.STATUS.RUNNING)
def check_precond(self):
super(SleepOperation, self).check_precond()
if self.instance.status not in ['RUNNING']:
......@@ -511,6 +528,10 @@ class WakeUpOperation(InstanceOperation):
Power on Virtual Machine and load its memory from dump.
def is_preferred(self):
return (self.instance.is_base and
self.instance.status == self.instance.STATUS.SUSPENDED)
def check_precond(self):
super(WakeUpOperation, self).check_precond()
if self.instance.status not in ['SUSPENDED']:
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