Move schedule task out of create instance flow

For multi instance creation scenario, we need to schedule for all
requested instances first then run the flow separately, so better
to move this task out, and leave the OnFailureReschedule task to
the flow.

Change-Id: If576003cd6a2db0dd90e2ee5cdf0b0cb00f6da63
This commit is contained in:
Zhenguo Niu 2017-03-23 15:21:05 +08:00
parent c2cf94d947
commit 7a341d8e04
6 changed files with 25 additions and 56 deletions

View File

@ -36,25 +36,6 @@ ACTION = 'instance:create'
CONF = cfg.CONF
class ScheduleCreateInstanceTask(flow_utils.MoganTask):
"""Activates a scheduler driver and handles any subsequent failure."""
def __init__(self, manager):
requires = ['filter_properties', 'request_spec', 'instance',
'context']
super(ScheduleCreateInstanceTask, self).__init__(addons=[ACTION],
requires=requires)
self.manager = manager
def execute(self, context, instance, request_spec, filter_properties):
top_node = self.manager.scheduler_rpcapi.select_destinations(
context,
request_spec,
filter_properties)
instance.node_uuid = top_node
instance.save()
class OnFailureRescheduleTask(flow_utils.MoganTask):
"""Triggers a rescheduling request to be sent when reverting occurs.
@ -246,9 +227,9 @@ def get_flow(context, manager, instance, requested_networks, request_spec,
This flow will do the following:
1. Schedule a node to create instance
3. Build networks for the instance and set port id back to baremetal port
4. Do node deploy and handle errors.
1. Build networks for the instance and set port id back to baremetal port
2. Do node deploy and handle errors.
3. Reschedule if the tasks are on failure.
"""
flow_name = ACTION.replace(":", "_") + "_manager"
@ -265,8 +246,7 @@ def get_flow(context, manager, instance, requested_networks, request_spec,
'requested_networks': requested_networks
}
instance_flow.add(ScheduleCreateInstanceTask(manager),
OnFailureRescheduleTask(manager.engine_rpcapi),
instance_flow.add(OnFailureRescheduleTask(manager.engine_rpcapi),
BuildNetworkTask(manager),
CreateInstanceTask(manager.driver))

View File

@ -326,6 +326,19 @@ class EngineManager(base_manager.BaseEngineManager):
if filter_properties is None:
filter_properties = {}
try:
node = self.scheduler_rpcapi.select_destinations(
context, request_spec, filter_properties)
instance.node_uuid = node['node_uuid']
instance.save()
except Exception as e:
utils.process_event(fsm, instance, event='error')
LOG.error(_LE("Created instance %(uuid)s failed."
"Exception: %(exception)s"),
{"uuid": instance.uuid,
"exception": e})
return
try:
flow_engine = create_instance.get_flow(
context,
@ -336,6 +349,7 @@ class EngineManager(base_manager.BaseEngineManager):
filter_properties,
)
except Exception:
utils.process_event(fsm, instance, event='error')
msg = _("Create manager instance flow failed.")
LOG.exception(msg)
raise exception.MoganException(msg)

View File

@ -189,8 +189,9 @@ class FilterScheduler(driver.Scheduler):
top_node = self._choose_top_node(weighed_nodes, request_spec)
top_node.obj.consume_from_request(context)
self._add_retry_node(filter_properties, top_node.obj.node)
return top_node.obj.node
self._add_retry_node(filter_properties, top_node.obj.node_uuid)
dest = dict(node_uuid=top_node.obj.node_uuid)
return dest
return _schedule(self, context, request_spec, filter_properties)

View File

@ -34,7 +34,7 @@ class NodeState(object):
"""Mutable and immutable information tracked for a Ironic node."""
def __init__(self, node):
self.node = node.node_uuid
self.node_uuid = node.node_uuid
self.capabilities = node.extra_specs
self.availability_zone = node.availability_zone \
or CONF.engine.default_availability_zone
@ -43,7 +43,7 @@ class NodeState(object):
def consume_from_request(self, context):
"""Consume the compute node."""
objects.ComputeNode.consume_node(context, self.node)
objects.ComputeNode.consume_node(context, self.node_uuid)
class NodeManager(object):

View File

@ -24,12 +24,12 @@ class WeighedNode(base_weight.WeighedObject):
def to_dict(self):
return {
'weight': self.weight,
'node': self.obj.node,
'node': self.obj.node_uuid,
}
def __repr__(self):
return ("WeighedNode [node: %s, weight: %s]" %
(self.obj.node, self.weight))
(self.obj.node_uuid, self.weight))
class BaseNodeWeigher(base_weight.BaseWeigher):

View File

@ -16,13 +16,11 @@
import mock
from oslo_context import context
from oslo_utils import uuidutils
from mogan.engine.baremetal.ironic import IronicDriver
from mogan.engine.flows import create_instance
from mogan.engine import manager
from mogan import objects
from mogan.scheduler import rpcapi as scheduler_rpcapi
from mogan.tests import base
from mogan.tests.unit.objects import utils as obj_utils
@ -33,30 +31,6 @@ class CreateInstanceFlowTestCase(base.TestCase):
super(CreateInstanceFlowTestCase, self).setUp()
self.ctxt = context.get_admin_context()
@mock.patch.object(objects.instance.Instance, 'save')
@mock.patch.object(scheduler_rpcapi.SchedulerAPI, 'select_destinations')
def test_schedule_task_execute(self, mock_schedule, mock_save):
fake_uuid = uuidutils.generate_uuid()
fake_engine_manager = mock.MagicMock()
sche_rpcapi = scheduler_rpcapi.SchedulerAPI()
fake_engine_manager.scheduler_rpcapi = sche_rpcapi
fake_request_spec = mock.MagicMock()
fake_filter_props = mock.MagicMock()
task = create_instance.ScheduleCreateInstanceTask(
fake_engine_manager)
instance_obj = obj_utils.get_test_instance(self.ctxt)
mock_schedule.return_value = fake_uuid
mock_save.side_effect = None
task.execute(self.ctxt,
instance_obj,
fake_request_spec,
fake_filter_props)
mock_schedule.assert_called_once_with(self.ctxt,
fake_request_spec,
fake_filter_props)
self.assertEqual(fake_uuid, instance_obj.node_uuid)
@mock.patch.object(objects.instance.Instance, 'save')
@mock.patch.object(create_instance.BuildNetworkTask, '_build_networks')
def test_create_network_task_execute(self, mock_build_networks, mock_save):