summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2023-02-15 19:44:16 +0000
committerGerrit Code Review <review@openstack.org>2023-02-15 19:44:16 +0000
commit59ac94158179fc53a87cc3c717dcacff33f2781e (patch)
tree71a784a3bd2dc32448878875d8988782379bb5f1
parent38592c28ab7e278d20ce935eb85ab62333e56d96 (diff)
parent87c0602537688c3da2291792a98caf9d9faf9d6c (diff)
downloadnova-59ac94158179fc53a87cc3c717dcacff33f2781e.tar.gz
Merge "Factor out a mixin class for candidate aware filters"
-rw-r--r--nova/scheduler/filters/__init__.py41
-rw-r--r--nova/scheduler/filters/numa_topology_filter.py40
-rw-r--r--nova/scheduler/filters/pci_passthrough_filter.py33
3 files changed, 65 insertions, 49 deletions
diff --git a/nova/scheduler/filters/__init__.py b/nova/scheduler/filters/__init__.py
index 74e24b7bc3..785a13279e 100644
--- a/nova/scheduler/filters/__init__.py
+++ b/nova/scheduler/filters/__init__.py
@@ -16,8 +16,12 @@
"""
Scheduler host filters
"""
+from oslo_log import log as logging
+
from nova import filters
+LOG = logging.getLogger(__name__)
+
class BaseHostFilter(filters.BaseFilter):
"""Base class for host filters."""
@@ -53,6 +57,43 @@ class BaseHostFilter(filters.BaseFilter):
raise NotImplementedError()
+class CandidateFilterMixin:
+ """Mixing that helps to implement a Filter that needs to filter host by
+ Placement allocation candidates.
+ """
+
+ def filter_candidates(self, host_state, filter_func):
+ """Checks still viable allocation candidates by the filter_func and
+ keep only those that are passing it.
+
+ :param host_state: HostState object holding the list of still viable
+ allocation candidates
+ :param filter_func: A callable that takes an allocation candidate and
+ returns a True like object if the candidate passed the filter or a
+ False like object if it doesn't.
+ """
+ good_candidates = []
+ for candidate in host_state.allocation_candidates:
+ LOG.debug(
+ f'{self.__class__.__name__} tries allocation candidate: '
+ f'{candidate}',
+ )
+ if filter_func(candidate):
+ LOG.debug(
+ f'{self.__class__.__name__} accepted allocation '
+ f'candidate: {candidate}',
+ )
+ good_candidates.append(candidate)
+ else:
+ LOG.debug(
+ f'{self.__class__.__name__} rejected allocation '
+ f'candidate: {candidate}',
+ )
+
+ host_state.allocation_candidates = good_candidates
+ return good_candidates
+
+
class HostFilterHandler(filters.BaseFilterHandler):
def __init__(self):
super(HostFilterHandler, self).__init__(BaseHostFilter)
diff --git a/nova/scheduler/filters/numa_topology_filter.py b/nova/scheduler/filters/numa_topology_filter.py
index 7ec9ca5648..ae50db90e5 100644
--- a/nova/scheduler/filters/numa_topology_filter.py
+++ b/nova/scheduler/filters/numa_topology_filter.py
@@ -20,7 +20,10 @@ from nova.virt import hardware
LOG = logging.getLogger(__name__)
-class NUMATopologyFilter(filters.BaseHostFilter):
+class NUMATopologyFilter(
+ filters.BaseHostFilter,
+ filters.CandidateFilterMixin,
+):
"""Filter on requested NUMA topology."""
# NOTE(sean-k-mooney): In change I0322d872bdff68936033a6f5a54e8296a6fb343
@@ -97,34 +100,19 @@ class NUMATopologyFilter(filters.BaseHostFilter):
if network_metadata:
limits.network_metadata = network_metadata
- good_candidates = []
- for candidate in host_state.allocation_candidates:
- LOG.debug(
- 'NUMATopologyFilter tries allocation candidate: %s, %s',
- candidate, requested_topology
- )
- instance_topology = (hardware.numa_fit_instance_to_host(
- host_topology, requested_topology,
+ good_candidates = self.filter_candidates(
+ host_state,
+ lambda candidate: hardware.numa_fit_instance_to_host(
+ host_topology,
+ requested_topology,
limits=limits,
pci_requests=pci_requests,
pci_stats=host_state.pci_stats,
- provider_mapping=candidate['mappings'],
- ))
- if instance_topology:
- LOG.debug(
- 'NUMATopologyFilter accepted allocation candidate: %s',
- candidate
- )
- good_candidates.append(candidate)
- else:
- LOG.debug(
- 'NUMATopologyFilter rejected allocation candidate: %s',
- candidate
- )
-
- host_state.allocation_candidates = good_candidates
-
- if not host_state.allocation_candidates:
+ provider_mapping=candidate["mappings"],
+ ),
+ )
+
+ if not good_candidates:
LOG.debug("%(host)s, %(node)s fails NUMA topology "
"requirements. The instance does not fit on this "
"host.", {'host': host_state.host,
diff --git a/nova/scheduler/filters/pci_passthrough_filter.py b/nova/scheduler/filters/pci_passthrough_filter.py
index 36f0b5901c..992879072a 100644
--- a/nova/scheduler/filters/pci_passthrough_filter.py
+++ b/nova/scheduler/filters/pci_passthrough_filter.py
@@ -20,7 +20,10 @@ from nova.scheduler import filters
LOG = logging.getLogger(__name__)
-class PciPassthroughFilter(filters.BaseHostFilter):
+class PciPassthroughFilter(
+ filters.BaseHostFilter,
+ filters.CandidateFilterMixin,
+):
"""Pci Passthrough Filter based on PCI request
Filter that schedules instances on a host if the host has devices
@@ -54,28 +57,12 @@ class PciPassthroughFilter(filters.BaseHostFilter):
{'host_state': host_state, 'requests': pci_requests})
return False
- good_candidates = []
- for candidate in host_state.allocation_candidates:
- LOG.debug(
- 'PciPassthroughFilter tries allocation candidate: %s',
- candidate
- )
- if host_state.pci_stats.support_requests(
- pci_requests.requests,
- provider_mapping=candidate['mappings']
- ):
- LOG.debug(
- 'PciPassthroughFilter accepted allocation candidate: %s',
- candidate
- )
- good_candidates.append(candidate)
- else:
- LOG.debug(
- 'PciPassthroughFilter rejected allocation candidate: %s',
- candidate
- )
-
- host_state.allocation_candidates = good_candidates
+ good_candidates = self.filter_candidates(
+ host_state,
+ lambda candidate: host_state.pci_stats.support_requests(
+ pci_requests.requests, provider_mapping=candidate["mappings"]
+ ),
+ )
if not good_candidates:
LOG.debug("%(host_state)s doesn't have the required PCI devices"