Verify requested_destination in the scheduler
Now that the RequestSpec provides a field for a requested destination, we can know if the admin user provided a destination to verify (and not force it). In order to verify this destination, we want to run the filters for only this host, so that if the filters are not okay for that possibility, the scheduler should raise a NoValidHost exception. For the moment, nothing is setting this field but the next patch will provide an API-level modification for putting it if the provided destination exists (and changing the behaviour if the admin provides the host field for evacuate and live-migrate) Change-Id: Ifb803c708e89b7101ded48571e1af49c33117758 Partially-Implements: blueprint check-destination-on-migrations
This commit is contained in:
parent
2358ebacd8
commit
7755b759b4
@ -505,10 +505,33 @@ class HostManager(object):
|
|||||||
"'force_nodes' value of '%s'")
|
"'force_nodes' value of '%s'")
|
||||||
LOG.info(msg % forced_nodes_str)
|
LOG.info(msg % forced_nodes_str)
|
||||||
|
|
||||||
|
def _get_hosts_matching_request(hosts, requested_destination):
|
||||||
|
(host, node) = (requested_destination.host,
|
||||||
|
requested_destination.node)
|
||||||
|
requested_nodes = [x for x in hosts
|
||||||
|
if x.host == host and x.nodename == node]
|
||||||
|
if requested_nodes:
|
||||||
|
LOG.info(_LI('Host filter only checking host %(host)s and '
|
||||||
|
'node %(node)s') % {'host': host, 'node': node})
|
||||||
|
else:
|
||||||
|
# NOTE(sbauza): The API level should prevent the user from
|
||||||
|
# providing a wrong destination but let's make sure a wrong
|
||||||
|
# destination doesn't trample the scheduler still.
|
||||||
|
LOG.info(_LI('No hosts matched due to not matching requested '
|
||||||
|
'destination (%(host)s, %(node)s)'
|
||||||
|
) % {'host': host, 'node': node})
|
||||||
|
return iter(requested_nodes)
|
||||||
|
|
||||||
ignore_hosts = spec_obj.ignore_hosts or []
|
ignore_hosts = spec_obj.ignore_hosts or []
|
||||||
force_hosts = spec_obj.force_hosts or []
|
force_hosts = spec_obj.force_hosts or []
|
||||||
force_nodes = spec_obj.force_nodes or []
|
force_nodes = spec_obj.force_nodes or []
|
||||||
|
requested_node = spec_obj.requested_destination
|
||||||
|
|
||||||
|
if requested_node is not None:
|
||||||
|
# NOTE(sbauza): Reduce a potentially long set of hosts as much as
|
||||||
|
# possible to any requested destination nodes before passing the
|
||||||
|
# list to the filters
|
||||||
|
hosts = _get_hosts_matching_request(hosts, requested_node)
|
||||||
if ignore_hosts or force_hosts or force_nodes:
|
if ignore_hosts or force_hosts or force_nodes:
|
||||||
# NOTE(deva): we can't assume "host" is unique because
|
# NOTE(deva): we can't assume "host" is unique because
|
||||||
# one host may have many nodes.
|
# one host may have many nodes.
|
||||||
|
@ -222,6 +222,40 @@ class HostManagerTestCase(test.NoDBTestCase):
|
|||||||
fake_properties)
|
fake_properties)
|
||||||
self._verify_result(info, result)
|
self._verify_result(info, result)
|
||||||
|
|
||||||
|
def test_get_filtered_hosts_with_requested_destination(self):
|
||||||
|
dest = objects.Destination(host='fake_host1', node='fake-node')
|
||||||
|
fake_properties = objects.RequestSpec(requested_destination=dest,
|
||||||
|
ignore_hosts=[],
|
||||||
|
instance_uuid='fake-uuid1',
|
||||||
|
force_hosts=[],
|
||||||
|
force_nodes=[])
|
||||||
|
|
||||||
|
info = {'expected_objs': [self.fake_hosts[0]],
|
||||||
|
'expected_fprops': fake_properties}
|
||||||
|
|
||||||
|
self._mock_get_filtered_hosts(info)
|
||||||
|
|
||||||
|
result = self.host_manager.get_filtered_hosts(self.fake_hosts,
|
||||||
|
fake_properties)
|
||||||
|
self._verify_result(info, result)
|
||||||
|
|
||||||
|
def test_get_filtered_hosts_with_wrong_requested_destination(self):
|
||||||
|
dest = objects.Destination(host='dummy', node='fake-node')
|
||||||
|
fake_properties = objects.RequestSpec(requested_destination=dest,
|
||||||
|
ignore_hosts=[],
|
||||||
|
instance_uuid='fake-uuid1',
|
||||||
|
force_hosts=[],
|
||||||
|
force_nodes=[])
|
||||||
|
|
||||||
|
info = {'expected_objs': [],
|
||||||
|
'expected_fprops': fake_properties}
|
||||||
|
|
||||||
|
self._mock_get_filtered_hosts(info)
|
||||||
|
|
||||||
|
result = self.host_manager.get_filtered_hosts(self.fake_hosts,
|
||||||
|
fake_properties)
|
||||||
|
self._verify_result(info, result)
|
||||||
|
|
||||||
def test_get_filtered_hosts_with_ignore(self):
|
def test_get_filtered_hosts_with_ignore(self):
|
||||||
fake_properties = objects.RequestSpec(
|
fake_properties = objects.RequestSpec(
|
||||||
instance_uuid=uuids.instance,
|
instance_uuid=uuids.instance,
|
||||||
|
Loading…
Reference in New Issue
Block a user