Merge branch 'feature-abortable-operations-rebased'
Feature Abortable Operations Make possible the implementation of abortable operations. Implement it for shutdown.
Showing
... | @@ -26,7 +26,9 @@ from django.utils.translation import ugettext_lazy as _ | ... | @@ -26,7 +26,9 @@ from django.utils.translation import ugettext_lazy as _ |
from celery.exceptions import TimeLimitExceeded | from celery.exceptions import TimeLimitExceeded | ||
from common.operations import Operation, register_operation | from common.operations import Operation, register_operation | ||
from .tasks.local_tasks import async_instance_operation, async_node_operation | from .tasks.local_tasks import ( | ||
abortable_async_instance_operation, abortable_async_node_operation, | |||
) | |||
from .models import ( | from .models import ( | ||
Instance, InstanceActivity, InstanceTemplate, Interface, Node, | Instance, InstanceActivity, InstanceTemplate, Interface, Node, | ||
NodeActivity, | NodeActivity, | ||
... | @@ -38,7 +40,7 @@ logger = getLogger(__name__) | ... | @@ -38,7 +40,7 @@ logger = getLogger(__name__) |
class InstanceOperation(Operation): | class InstanceOperation(Operation): | ||
acl_level = 'owner' | acl_level = 'owner' | ||
async_operation = async_instance_operation | async_operation = abortable_async_instance_operation | ||
host_cls = Instance | host_cls = Instance | ||
def __init__(self, instance): | def __init__(self, instance): | ||
... | @@ -126,7 +128,7 @@ class DeployOperation(InstanceOperation): | ... | @@ -126,7 +128,7 @@ class DeployOperation(InstanceOperation): |
def on_commit(self, activity): | def on_commit(self, activity): | ||
activity.resultant_state = 'RUNNING' | activity.resultant_state = 'RUNNING' | ||
def _operation(self, activity, user, system, timeout=15): | def _operation(self, activity, timeout=15): | ||
# Allocate VNC port and host node | # Allocate VNC port and host node | ||
self.instance.allocate_vnc_port() | self.instance.allocate_vnc_port() | ||
self.instance.allocate_node() | self.instance.allocate_node() | ||
... | @@ -162,7 +164,7 @@ class DestroyOperation(InstanceOperation): | ... | @@ -162,7 +164,7 @@ class DestroyOperation(InstanceOperation): |
def on_commit(self, activity): | def on_commit(self, activity): | ||
activity.resultant_state = 'DESTROYED' | activity.resultant_state = 'DESTROYED' | ||
def _operation(self, activity, user, system): | def _operation(self, activity): | ||
if self.instance.node: | if self.instance.node: | ||
# Destroy networks | # Destroy networks | ||
with activity.sub_activity('destroying_net'): | with activity.sub_activity('destroying_net'): | ||
... | @@ -200,7 +202,7 @@ class MigrateOperation(InstanceOperation): | ... | @@ -200,7 +202,7 @@ class MigrateOperation(InstanceOperation): |
name = _("migrate") | name = _("migrate") | ||
description = _("Live migrate running VM to another node.") | description = _("Live migrate running VM to another node.") | ||
def _operation(self, activity, user, system, to_node=None, timeout=120): | def _operation(self, activity, to_node=None, timeout=120): | ||
if not to_node: | if not to_node: | ||
with activity.sub_activity('scheduling') as sa: | with activity.sub_activity('scheduling') as sa: | ||
to_node = self.instance.select_node() | to_node = self.instance.select_node() | ||
... | @@ -230,7 +232,7 @@ class RebootOperation(InstanceOperation): | ... | @@ -230,7 +232,7 @@ class RebootOperation(InstanceOperation): |
name = _("reboot") | name = _("reboot") | ||
description = _("Reboot virtual machine with Ctrl+Alt+Del signal.") | description = _("Reboot virtual machine with Ctrl+Alt+Del signal.") | ||
def _operation(self, activity, user, system, timeout=5): | def _operation(self, timeout=5): | ||
self.instance.reboot_vm(timeout=timeout) | self.instance.reboot_vm(timeout=timeout) | ||
... | @@ -280,7 +282,7 @@ class ResetOperation(InstanceOperation): | ... | @@ -280,7 +282,7 @@ class ResetOperation(InstanceOperation): |
name = _("reset") | name = _("reset") | ||
description = _("Reset virtual machine (reset button).") | description = _("Reset virtual machine (reset button).") | ||
def _operation(self, activity, user, system, timeout=5): | def _operation(self, timeout=5): | ||
self.instance.reset_vm(timeout=timeout) | self.instance.reset_vm(timeout=timeout) | ||
register_operation(ResetOperation) | register_operation(ResetOperation) | ||
... | @@ -295,6 +297,7 @@ class SaveAsTemplateOperation(InstanceOperation): | ... | @@ -295,6 +297,7 @@ class SaveAsTemplateOperation(InstanceOperation): |
Template can be shared with groups and users. | Template can be shared with groups and users. | ||
Users can instantiate Virtual Machines from Templates. | Users can instantiate Virtual Machines from Templates. | ||
""") | """) | ||
abortable = True | |||
@staticmethod | @staticmethod | ||
def _rename(name): | def _rename(name): | ||
... | @@ -307,11 +310,11 @@ class SaveAsTemplateOperation(InstanceOperation): | ... | @@ -307,11 +310,11 @@ class SaveAsTemplateOperation(InstanceOperation): |
return "%s v%d" % (name, v) | return "%s v%d" % (name, v) | ||
def _operation(self, activity, user, system, timeout=300, name=None, | def _operation(self, activity, user, system, timeout=300, name=None, | ||
with_shutdown=True, **kwargs): | with_shutdown=True, task=None, **kwargs): | ||
if with_shutdown: | if with_shutdown: | ||
try: | try: | ||
ShutdownOperation(self.instance).call(parent_activity=activity, | ShutdownOperation(self.instance).call(parent_activity=activity, | ||
user=user) | user=user, task=task) | ||
except Instance.WrongStateError: | except Instance.WrongStateError: | ||
pass | pass | ||
... | @@ -370,23 +373,18 @@ class ShutdownOperation(InstanceOperation): | ... | @@ -370,23 +373,18 @@ class ShutdownOperation(InstanceOperation): |
id = 'shutdown' | id = 'shutdown' | ||
name = _("shutdown") | name = _("shutdown") | ||
description = _("Shutdown virtual machine with ACPI signal.") | description = _("Shutdown virtual machine with ACPI signal.") | ||
abortable = True | |||
def check_precond(self): | def check_precond(self): | ||
super(ShutdownOperation, self).check_precond() | super(ShutdownOperation, self).check_precond() | ||
if self.instance.status not in ['RUNNING']: | if self.instance.status not in ['RUNNING']: | ||
raise self.instance.WrongStateError(self.instance) | raise self.instance.WrongStateError(self.instance) | ||
def on_abort(self, activity, error): | |||
if isinstance(error, TimeLimitExceeded): | |||
activity.resultant_state = None | |||
else: | |||
activity.resultant_state = 'ERROR' | |||
def on_commit(self, activity): | def on_commit(self, activity): | ||
activity.resultant_state = 'STOPPED' | activity.resultant_state = 'STOPPED' | ||
def _operation(self, activity, user, system, timeout=120): | def _operation(self, task=None): | ||
self.instance.shutdown_vm(timeout=timeout) | self.instance.shutdown_vm(task=task) | ||
self.instance.yield_node() | self.instance.yield_node() | ||
self.instance.yield_vnc_port() | self.instance.yield_vnc_port() | ||
... | @@ -403,7 +401,7 @@ class ShutOffOperation(InstanceOperation): | ... | @@ -403,7 +401,7 @@ class ShutOffOperation(InstanceOperation): |
def on_commit(self, activity): | def on_commit(self, activity): | ||
activity.resultant_state = 'STOPPED' | activity.resultant_state = 'STOPPED' | ||
def _operation(self, activity, user, system): | < |