Coverage for manila/scheduler/weighers/goodness.py: 98%

46 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 import utils 

20from manila.scheduler.weighers import base_host 

21 

22 

23LOG = logging.getLogger(__name__) 

24 

25 

26class GoodnessWeigher(base_host.BaseHostWeigher): 

27 """Goodness Weigher. Assign weights based on a host's goodness function. 

28 

29 Goodness rating is the following: 

30 

31 .. code-block:: none 

32 

33 0 -- host is a poor choice 

34 . 

35 . 

36 50 -- host is a good choice 

37 . 

38 . 

39 100 -- host is a perfect choice 

40 

41 """ 

42 

43 def _weigh_object(self, host_state, weight_properties): 

44 """Determine host's goodness rating based on a goodness_function.""" 

45 stats = self._generate_stats(host_state, weight_properties) 

46 LOG.debug("Checking host '%s'", stats['host_stats']['host']) 

47 result = self._check_goodness_function(stats) 

48 LOG.debug("Goodness: %s", result) 

49 LOG.debug("Done checking host '%s'", stats['host_stats']['host']) 

50 

51 return result 

52 

53 def _check_goodness_function(self, stats): 

54 """Gets a host's goodness rating based on its goodness function.""" 

55 

56 goodness_rating = 0 

57 

58 if stats['goodness_function'] is None: 

59 LOG.warning("Goodness function not set :: defaulting to " 

60 "minimal goodness rating of 0.") 

61 else: 

62 try: 

63 goodness_result = self._run_evaluator( 

64 stats['goodness_function'], 

65 stats) 

66 except Exception as ex: 

67 LOG.warning("Error in goodness_function function " 

68 "'%(function)s' : '%(error)s' :: Defaulting " 

69 "to a goodness of 0.", 

70 {'function': stats['goodness_function'], 

71 'error': ex, }) 

72 return goodness_rating 

73 

74 if type(goodness_result) is bool: 

75 if goodness_result: 75 ↛ 85line 75 didn't jump to line 85 because the condition on line 75 was always true

76 goodness_rating = 100 

77 elif goodness_result < 0 or goodness_result > 100: 

78 LOG.warning("Invalid goodness result. Result must be " 

79 "between 0 and 100. Result generated: '%s' " 

80 ":: Defaulting to a goodness of 0.", 

81 goodness_result) 

82 else: 

83 goodness_rating = goodness_result 

84 

85 msg = "Goodness function result for host %(host)s: %(result)s." 

86 args = {'host': stats['host_stats']['host'], 

87 'result': str(goodness_rating)} 

88 LOG.info(msg, args) 

89 

90 return goodness_rating 

91 

92 def _run_evaluator(self, func, stats): 

93 """Evaluates a given function using the provided available stats.""" 

94 host_stats = stats['host_stats'] 

95 host_caps = stats['host_caps'] 

96 extra_specs = stats['extra_specs'] 

97 share_stats = stats['share_stats'] 

98 

99 result = evaluator.evaluate( 

100 func, 

101 extra=extra_specs, 

102 stats=host_stats, 

103 capabilities=host_caps, 

104 share=share_stats) 

105 

106 return result 

107 

108 def _generate_stats(self, host_state, weight_properties): 

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

110 

111 goodness_function = None 

112 

113 if ('goodness_function' in host_state.capabilities and 

114 host_state.capabilities['goodness_function'] is not None): 

115 goodness_function = str( 

116 host_state.capabilities['goodness_function']) 

117 

118 stats = utils.generate_stats(host_state, weight_properties) 

119 

120 stats['goodness_function'] = goodness_function 

121 

122 return stats