Coverage for nova/compute/monitors/__init__.py: 95%

29 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-24 11:16 +0000

1# Copyright 2013 Intel Corporation. 

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 

16""" 

17Resource monitor API specification. 

18""" 

19 

20from oslo_log import log as logging 

21from stevedore import enabled 

22 

23import nova.conf 

24 

25CONF = nova.conf.CONF 

26LOG = logging.getLogger(__name__) 

27 

28 

29class MonitorHandler(object): 

30 

31 NAMESPACES = [ 

32 'nova.compute.monitors.cpu', 

33 ] 

34 

35 def __init__(self, resource_tracker): 

36 # Dictionary keyed by the monitor type namespace. Value is the 

37 # first loaded monitor of that namespace or False. 

38 self.type_monitor_loaded = {ns: False for ns in self.NAMESPACES} 

39 

40 self.monitors = [] 

41 for ns in self.NAMESPACES: 

42 plugin_mgr = enabled.EnabledExtensionManager( 

43 namespace=ns, 

44 invoke_on_load=True, 

45 check_func=self.check_enabled_monitor, 

46 invoke_args=(resource_tracker,) 

47 ) 

48 self.monitors += [ext.obj for ext in plugin_mgr] 

49 

50 def check_enabled_monitor(self, ext): 

51 """Ensures that only one monitor is specified of any type.""" 

52 # The extension does not have a namespace attribute, unfortunately, 

53 # but we can get the namespace by examining the first part of the 

54 # entry_point_target attribute, which looks like this: 

55 # 'nova.compute.monitors.cpu.virt_driver:Monitor' 

56 ept = ext.entry_point_target 

57 ept_parts = ept.split(':') 

58 namespace_parts = ept_parts[0].split('.') 

59 namespace = '.'.join(namespace_parts[0:-1]) 

60 if self.type_monitor_loaded[namespace] is not False: 

61 LOG.warning("Excluding %(namespace)s monitor " 

62 "%(monitor_name)s. Already loaded " 

63 "%(loaded_monitor)s.", 

64 {'namespace': namespace, 

65 'monitor_name': ext.name, 

66 'loaded_monitor': self.type_monitor_loaded[namespace] 

67 }) 

68 return False 

69 

70 # NOTE(jaypipes): We used to only have CPU monitors, so 

71 # CONF.compute_monitors could contain "virt_driver" without any monitor 

72 # type namespace. So, to maintain backwards-compatibility with that 

73 # older way of specifying monitors, we first loop through any values in 

74 # CONF.compute_monitors and put any non-namespace'd values into the 

75 # 'cpu' namespace. 

76 cfg_monitors = ['cpu.' + cfg if '.' not in cfg else cfg 

77 for cfg in CONF.compute_monitors] 

78 # NOTE(jaypipes): Append 'nova.compute.monitors.' to any monitor value 

79 # that doesn't have it to allow CONF.compute_monitors to use shortened 

80 # namespaces (like 'cpu.' instead of 'nova.compute.monitors.cpu.') 

81 cfg_monitors = ['nova.compute.monitors.' + cfg 

82 if 'nova.compute.monitors.' not in cfg else cfg 

83 for cfg in cfg_monitors] 

84 if namespace + '.' + ext.name in cfg_monitors: 

85 self.type_monitor_loaded[namespace] = ext.name 

86 return True 

87 # Only log something if compute_monitors is not empty. 

88 if CONF.compute_monitors: 88 ↛ 89line 88 didn't jump to line 89 because the condition on line 88 was never true

89 LOG.warning("Excluding %(namespace)s monitor %(monitor_name)s. " 

90 "Not in the list of enabled monitors " 

91 "(CONF.compute_monitors).", 

92 {'namespace': namespace, 'monitor_name': ext.name}) 

93 return False