Commit cbf6979a by Őry Máté

vm: add new Node operations

parent 494dc514
...@@ -27,7 +27,7 @@ from django.db.models import ( ...@@ -27,7 +27,7 @@ from django.db.models import (
FloatField, permalink, FloatField, permalink,
) )
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _, ugettext_noop from django.utils.translation import ugettext_lazy as _
from celery.exceptions import TimeoutError from celery.exceptions import TimeoutError
from model_utils.models import TimeStampedModel from model_utils.models import TimeStampedModel
...@@ -37,7 +37,7 @@ from common.models import method_cache, WorkerNotFound, HumanSortField ...@@ -37,7 +37,7 @@ from common.models import method_cache, WorkerNotFound, HumanSortField
from common.operations import OperatedMixin from common.operations import OperatedMixin
from firewall.models import Host from firewall.models import Host
from ..tasks import vm_tasks from ..tasks import vm_tasks
from .activity import node_activity, NodeActivity from .activity import NodeActivity
from .common import Trait from .common import Trait
...@@ -145,31 +145,8 @@ class Node(OperatedMixin, TimeStampedModel): ...@@ -145,31 +145,8 @@ class Node(OperatedMixin, TimeStampedModel):
def get_status_display(self): def get_status_display(self):
return self.STATES[self.enabled][self.online][1] return self.STATES[self.enabled][self.online][1]
def disable(self, user=None, base_activity=None):
''' Disable the node.'''
if self.enabled:
if base_activity:
act_ctx = base_activity.sub_activity(
'disable', readable_name=ugettext_noop("disable node"))
else:
act_ctx = node_activity(
'disable', node=self, user=user,
readable_name=ugettext_noop("disable node"))
with act_ctx:
self.enabled = False
self.save()
def enable(self, user=None, base_activity=None): def enable(self, user=None, base_activity=None):
''' Enable the node. ''' raise NotImplementedError("Use activate or passivate instead.")
if self.enabled is not True:
if base_activity:
act_ctx = base_activity.sub_activity('enable')
else:
act_ctx = node_activity('enable', node=self, user=user)
with act_ctx:
self.enabled = True
self.save()
self.get_info(invalidate_cache=True)
@property @property
@node_available @node_available
......
...@@ -803,11 +803,20 @@ class ChangeStateOperation(InstanceOperation): ...@@ -803,11 +803,20 @@ class ChangeStateOperation(InstanceOperation):
class NodeOperation(Operation): class NodeOperation(Operation):
async_operation = abortable_async_node_operation async_operation = abortable_async_node_operation
host_cls = Node host_cls = Node
online_required = True
superuser_required = True
def __init__(self, node): def __init__(self, node):
super(NodeOperation, self).__init__(subject=node) super(NodeOperation, self).__init__(subject=node)
self.node = node self.node = node
def check_precond(self):
super(NodeOperation, self).check_precond()
if self.online_required and not self.node.online:
raise humanize_exception(ugettext_noop(
"You cannot call this operation on an offline node."),
Exception())
def create_activity(self, parent, user, kwargs): def create_activity(self, parent, user, kwargs):
name = self.get_activity_name(kwargs) name = self.get_activity_name(kwargs)
if parent: if parent:
...@@ -833,20 +842,14 @@ class FlushOperation(NodeOperation): ...@@ -833,20 +842,14 @@ class FlushOperation(NodeOperation):
activity_code_suffix = 'flush' activity_code_suffix = 'flush'
id = 'flush' id = 'flush'
name = _("flush") name = _("flush")
description = _("Disable node and move all instances to other ones.") description = _("Passivate node and move all instances to other ones.")
required_perms = () required_perms = ()
superuser_required = True
async_queue = "localhost.man.slow" async_queue = "localhost.man.slow"
def on_abort(self, activity, error):
from manager.scheduler import TraitsUnsatisfiableException
if isinstance(error, TraitsUnsatisfiableException):
if self.node_enabled:
self.node.enable(activity.user, activity)
def _operation(self, activity, user): def _operation(self, activity, user):
self.node_enabled = self.node.enabled if self.node.schedule_enabled:
self.node.disable(user, activity) PassivateOperation(self.node).call(parent_activity=activity,
user=user)
for i in self.node.instance_set.all(): for i in self.node.instance_set.all():
name = create_readable(ugettext_noop( name = create_readable(ugettext_noop(
"migrate %(instance)s (%(pk)s)"), instance=i.name, pk=i.pk) "migrate %(instance)s (%(pk)s)"), instance=i.name, pk=i.pk)
...@@ -855,6 +858,72 @@ class FlushOperation(NodeOperation): ...@@ -855,6 +858,72 @@ class FlushOperation(NodeOperation):
i.migrate(user=user) i.migrate(user=user)
@register_operation
class ActivateOperation(NodeOperation):
activity_code_suffix = 'activate'
id = 'activate'
name = _("activate")
description = _("Make node active, i.e. scheduler is allowed to deploy "
"virtual machines to it.")
required_perms = ()
def check_precond(self):
super(ActivateOperation, self).check_precond()
if self.node.enabled and self.node.schedule_enabled:
raise humanize_exception(ugettext_noop(
"You cannot activate an active node."), Exception())
def _operation(self):
self.node.enabled = True
self.node.schedule_enabled = True
self.node.save()
@register_operation
class PassivateOperation(NodeOperation):
activity_code_suffix = 'passivate'
id = 'passivate'
name = _("passivate")
description = _("Make node passive, i.e. scheduler is denied to deploy "
"virtual machines to it, but remaining instances and "
"the ones manually migrated will continue running.")
required_perms = ()
def check_precond(self):
if self.node.enabled and not self.node.schedule_enabled:
raise humanize_exception(ugettext_noop(
"You cannot passivate a passive node."), Exception())
super(PassivateOperation, self).check_precond()
def _operation(self):
self.node.enabled = True
self.node.schedule_enabled = False
self.node.save()
@register_operation
class DisableOperation(NodeOperation):
activity_code_suffix = 'disable'
id = 'disable'
name = _("disable")
description = _("Disable node.")
required_perms = ()
online_required = False
def check_precond(self):
if not self.node.enabled:
raise humanize_exception(ugettext_noop(
"You cannot disable a disabled node."), Exception())
if self.node.instance_set.exists():
raise humanize_exception(ugettext_noop(
"You cannot disable a node which is hosting instances."),
Exception())
super(DisableOperation, self).check_precond()
def _operation(self):
self.node.enabled = False
self.node.schedule_enabled = False
self.node.save()
@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