placement: refactor driver select_destinations()

Refactors the scheduler *driver* class select_destinations() method to
return a sorted list of HostState objects instead of a list of dicts.

This allows us to eventually use these HostState objects in our claim
logic in future patches.

Change-Id: I8f173fc36af249150e656f4a611c5ea6f2141ae3
blueprint: placement-allocation-requests
This commit is contained in:
Jay Pipes 2017-06-27 11:53:35 -04:00
parent 4eabef5a5c
commit aabda4a131
7 changed files with 23 additions and 16 deletions

View File

@ -65,7 +65,7 @@ class ChanceScheduler(driver.Scheduler):
dests = []
for i in range(num_instances):
host = self._schedule(context, CONF.compute_topic, spec_obj)
host_state = dict(host=host, nodename=None, limits=None)
host_state = self.host_manager.host_state_cls(host, None, None)
dests.append(host_state)
if len(dests) < num_instances:

View File

@ -56,9 +56,8 @@ class Scheduler(object):
@abc.abstractmethod
def select_destinations(self, context, spec_obj, instance_uuids):
"""Must override select_destinations method.
:return: A list of dicts with 'host', 'nodename' and 'limits' as keys
that satisfies the request_spec and filter_properties.
"""Returns a list of HostState objects that have been chosen by the
scheduler driver, one for each requested instance
(spec_obj.num_instances)
"""
return []

View File

@ -48,7 +48,9 @@ class FilterScheduler(driver.Scheduler):
self.scheduler_client = scheduler_client.SchedulerClient()
def select_destinations(self, context, spec_obj, instance_uuids):
"""Selects a filtered set of hosts and nodes."""
"""Returns a sorted list of HostState objects that satisfy the
supplied request_spec.
"""
self.notifier.info(
context, 'scheduler.select_destinations.start',
dict(request_spec=spec_obj.to_legacy_request_spec_dict()))
@ -77,13 +79,10 @@ class FilterScheduler(driver.Scheduler):
reason = _('There are not enough hosts available.')
raise exception.NoValidHost(reason=reason)
dests = [dict(host=host.obj.host, nodename=host.obj.nodename,
limits=host.obj.limits) for host in selected_hosts]
self.notifier.info(
context, 'scheduler.select_destinations.end',
dict(request_spec=spec_obj.to_legacy_request_spec_dict()))
return dests
return [host.obj for host in selected_hosts]
def _schedule(self, context, spec_obj, instance_uuids):
"""Returns a list of hosts that meet the required specs,

View File

@ -41,6 +41,14 @@ CONF = nova.conf.CONF
QUOTAS = quota.QUOTAS
def _host_state_obj_to_dict(host_state):
return {
'host': host_state.host,
'nodename': host_state.nodename,
'limits': host_state.limits,
}
class SchedulerManager(manager.Manager):
"""Chooses a host to run instances on."""
@ -96,7 +104,8 @@ class SchedulerManager(manager.Manager):
request_spec,
filter_properties)
dests = self.driver.select_destinations(ctxt, spec_obj, instance_uuids)
return jsonutils.to_primitive(dests)
dest_dicts = [_host_state_obj_to_dict(d) for d in dests]
return jsonutils.to_primitive(dest_dicts)
def update_aggregates(self, ctxt, aggregates):
"""Updates HostManager internal aggregates information.

View File

@ -97,7 +97,7 @@ class CachingSchedulerTestCase(test_scheduler.SchedulerTestCase):
result = self._test_select_destinations(spec_obj)
self.assertEqual(1, len(result))
self.assertEqual(result[0]["host"], fake_host.host)
self.assertEqual(result[0].host, fake_host.host)
def _test_select_destinations(self, spec_obj):
return self.driver.select_destinations(
@ -224,7 +224,7 @@ class CachingSchedulerTestCase(test_scheduler.SchedulerTestCase):
}
d = self.driver.select_destinations(self.context, spec_obj,
[spec_obj.instance_uuid])
self.assertIn(d[0]['host'], [hs.host for hs in host_states_cell2])
self.assertIn(d[0].host, [hs.host for hs in host_states_cell2])
if __name__ == '__main__':

View File

@ -67,10 +67,10 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase):
[uuids.instance1, uuids.instance2])
self.assertEqual(2, len(dests))
(host, node) = (dests[0]['host'], dests[0]['nodename'])
(host, node) = (dests[0].host, dests[0].nodename)
self.assertEqual('host3', host)
self.assertIsNone(node)
(host, node) = (dests[1]['host'], dests[1]['nodename'])
(host, node) = (dests[1].host, dests[1].nodename)
self.assertEqual('host2', host)
self.assertIsNone(node)

View File

@ -322,7 +322,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
dests = self.driver.select_destinations(self.context, spec_obj,
instance_uuids)
(host, node) = (dests[0]['host'], dests[0]['nodename'])
(host, node) = (dests[0].host, dests[0].nodename)
self.assertEqual(host, selected_hosts[0])
self.assertEqual(node, selected_nodes[0])