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

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. 

15 

16from oslo_log import log as logging 

17 

18from manila.scheduler.evaluator import evaluator 

19from manila.scheduler.filters import base_host 

20from manila.scheduler import utils 

21 

22 

23LOG = logging.getLogger(__name__) 

24 

25 

26class DriverFilter(base_host.BaseHostFilter): 

27 """DriverFilter filters hosts based on a 'filter function' and metrics. 

28 

29 DriverFilter filters based on share host's provided 'filter function' 

30 and metrics. 

31 """ 

32 

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) 

36 

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']) 

42 

43 return result 

44 

45 def _check_filter_function(self, stats): 

46 """Checks if a share passes a host's filter function. 

47 

48 Returns a tuple in the format (filter_passing, filter_invalid). 

49 Both values are booleans. 

50 """ 

51 

52 if stats['filter_function'] is None: 

53 LOG.debug("Filter function not set :: passing host.") 

54 return True 

55 

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 

67 

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) 

72 

73 return filter_result 

74 

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'] 

81 

82 result = evaluator.evaluate( 

83 func, 

84 extra=extra_specs, 

85 stats=host_stats, 

86 capabilities=host_caps, 

87 share=share_stats) 

88 

89 return result 

90 

91 def _generate_stats(self, host_state, filter_properties): 

92 """Generates statistics from host and share data.""" 

93 

94 filter_function = None 

95 

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']) 

100 

101 stats = utils.generate_stats(host_state, filter_properties) 

102 

103 stats['filter_function'] = filter_function 

104 

105 return stats