Coverage for nova/scheduler/filters/__init__.py: 91%
28 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-17 15:08 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-17 15:08 +0000
1# Copyright (c) 2011 OpenStack Foundation
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16"""
17Scheduler host filters
18"""
19from oslo_log import log as logging
21from nova import filters
23LOG = logging.getLogger(__name__)
26class BaseHostFilter(filters.BaseFilter):
27 """Base class for host filters."""
29 # This is set to True if this filter should be run for rebuild.
30 # For example, with rebuild, we need to ask the scheduler if the
31 # existing host is still legit for a rebuild with the new image and
32 # other parameters. We care about running policy filters (i.e.
33 # ImagePropertiesFilter) but not things that check usage on the
34 # existing compute node, etc.
35 # This also means that filters marked with RUN_ON_REBUILD = True cannot
36 # filter on allocation candidates or need to handle the rebuild case
37 # specially.
38 RUN_ON_REBUILD = False
40 def _filter_one(self, obj, spec):
41 """Return True if the object passes the filter, otherwise False."""
42 # Do this here so we don't get scheduler.filters.utils
43 from nova.scheduler import utils
44 if not self.RUN_ON_REBUILD and utils.request_is_rebuild(spec): 44 ↛ 46line 44 didn't jump to line 46 because the condition on line 44 was never true
45 # If we don't filter, default to passing the host.
46 return True
47 else:
48 # We are either a rebuild filter, in which case we always run,
49 # or this request is not rebuild in which case all filters
50 # should run.
51 return self.host_passes(obj, spec)
53 def host_passes(self, host_state, filter_properties):
54 """Return True if the HostState passes the filter, otherwise False.
55 Override this in a subclass.
56 """
57 raise NotImplementedError()
60class CandidateFilterMixin:
61 """Mixing that helps to implement a Filter that needs to filter host by
62 Placement allocation candidates.
63 """
65 def filter_candidates(self, host_state, filter_func):
66 """Checks still viable allocation candidates by the filter_func and
67 keep only those that are passing it.
69 :param host_state: HostState object holding the list of still viable
70 allocation candidates
71 :param filter_func: A callable that takes an allocation candidate and
72 returns a True like object if the candidate passed the filter or a
73 False like object if it doesn't.
74 """
75 good_candidates = []
76 for candidate in host_state.allocation_candidates:
77 LOG.debug(
78 f'{self.__class__.__name__} tries allocation candidate: '
79 f'{candidate}',
80 )
81 if filter_func(candidate):
82 LOG.debug(
83 f'{self.__class__.__name__} accepted allocation '
84 f'candidate: {candidate}',
85 )
86 good_candidates.append(candidate)
87 else:
88 LOG.debug(
89 f'{self.__class__.__name__} rejected allocation '
90 f'candidate: {candidate}',
91 )
93 host_state.allocation_candidates = good_candidates
94 return good_candidates
97class HostFilterHandler(filters.BaseFilterHandler):
98 def __init__(self):
99 super(HostFilterHandler, self).__init__(BaseHostFilter)
102def all_filters():
103 """Return a list of filter classes found in this directory.
105 This method is used as the default for available scheduler filters
106 and should return a list of all filter classes available.
107 """
108 return HostFilterHandler().get_all_classes()