Commit cbf6979a by Őry Máté

vm: add new Node operations

parent 494dc514
......@@ -27,7 +27,7 @@ from django.db.models import (
FloatField, permalink,
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 model_utils.models import TimeStampedModel
......@@ -37,7 +37,7 @@ from common.models import method_cache, WorkerNotFound, HumanSortField
from common.operations import OperatedMixin
from firewall.models import Host
from ..tasks import vm_tasks
from .activity import node_activity, NodeActivity
from .activity import NodeActivity
from .common import Trait
......@@ -145,31 +145,8 @@ class Node(OperatedMixin, TimeStampedModel):
def get_status_display(self):
return self.STATES[self.enabled][][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"))
act_ctx = node_activity(
'disable', node=self, user=user,
readable_name=ugettext_noop("disable node"))
with act_ctx:
self.enabled = False
def enable(self, user=None, base_activity=None):
''' Enable the node. '''
if self.enabled is not True:
if base_activity:
act_ctx = base_activity.sub_activity('enable')
act_ctx = node_activity('enable', node=self, user=user)
with act_ctx:
self.enabled = True
raise NotImplementedError("Use activate or passivate instead.")
......@@ -803,11 +803,20 @@ class ChangeStateOperation(InstanceOperation):
class NodeOperation(Operation):
async_operation = abortable_async_node_operation
host_cls = Node
online_required = True
superuser_required = True
def __init__(self, node):
super(NodeOperation, self).__init__(subject=node)
self.node = node
def check_precond(self):
super(NodeOperation, self).check_precond()
if self.online_required and not
raise humanize_exception(ugettext_noop(
"You cannot call this operation on an offline node."),
def create_activity(self, parent, user, kwargs):
name = self.get_activity_name(kwargs)
if parent:
......@@ -833,20 +842,14 @@ class FlushOperation(NodeOperation):
activity_code_suffix = 'flush'
id = '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 = ()
superuser_required = True
async_queue = ""
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):
self.node_enabled = self.node.enabled
self.node.disable(user, activity)
if self.node.schedule_enabled:
for i in self.node.instance_set.all():
name = create_readable(ugettext_noop(
"migrate %(instance)s (%(pk)s)"),,
......@@ -855,6 +858,72 @@ class FlushOperation(NodeOperation):
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
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
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."),
super(DisableOperation, self).check_precond()
def _operation(self):
self.node.enabled = False
self.node.schedule_enabled = False
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