Coverage for manila/scheduler/filters/driver.py: 100%
40 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
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.
16from oslo_log import log as logging
18from manila.scheduler.evaluator import evaluator
19from manila.scheduler.filters import base_host
20from manila.scheduler import utils
23LOG = logging.getLogger(__name__)
26class DriverFilter(base_host.BaseHostFilter):
27 """DriverFilter filters hosts based on a 'filter function' and metrics.
29 DriverFilter filters based on share host's provided 'filter function'
30 and metrics.
31 """
33 def host_passes(self, host_state, filter_properties):
34 """Determines whether a host has a passing filter_function or not."""
35 stats = self._generate_stats(host_state, filter_properties)
37 LOG.debug("Driver Filter: Checking host '%s'",
38 stats['host_stats']['host'])
39 result = self._check_filter_function(stats)
40 LOG.debug("Result: %s", result)
41 LOG.debug("Done checking host '%s'", stats['host_stats']['host'])
43 return result
45 def _check_filter_function(self, stats):
46 """Checks if a share passes a host's filter function.
48 Returns a tuple in the format (filter_passing, filter_invalid).
49 Both values are booleans.
50 """
52 if stats['filter_function'] is None:
53 LOG.debug("Filter function not set :: passing host.")
54 return True
56 try:
57 filter_result = self._run_evaluator(stats['filter_function'],
58 stats)
59 except Exception as ex:
60 # Warn the admin for now that there is an error in the
61 # filter function.
62 LOG.warning("Error in filtering function "
63 "'%(function)s' : '%(error)s' :: failing host.",
64 {'function': stats['filter_function'],
65 'error': ex, })
66 return False
68 msg = "Filter function result for host %(host)s: %(result)s."
69 args = {'host': stats['host_stats']['host'],
70 'result': str(filter_result)}
71 LOG.info(msg, args)
73 return filter_result
75 def _run_evaluator(self, func, stats):
76 """Evaluates a given function using the provided available stats."""
77 host_stats = stats['host_stats']
78 host_caps = stats['host_caps']
79 extra_specs = stats['extra_specs']
80 share_stats = stats['share_stats']
82 result = evaluator.evaluate(
83 func,
84 extra=extra_specs,
85 stats=host_stats,
86 capabilities=host_caps,
87 share=share_stats)
89 return result
91 def _generate_stats(self, host_state, filter_properties):
92 """Generates statistics from host and share data."""
94 filter_function = None
96 if ('filter_function' in host_state.capabilities and
97 host_state.capabilities['filter_function'] is not None):
98 filter_function = str(
99 host_state.capabilities['filter_function'])
101 stats = utils.generate_stats(host_state, filter_properties)
103 stats['filter_function'] = filter_function
105 return stats