Coverage for nova/manager.py: 97%

33 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-17 15:08 +0000

1# Copyright 2010 United States Government as represented by the 

2# Administrator of the National Aeronautics and Space Administration. 

3# All Rights Reserved. 

4# 

5# Licensed under the Apache License, Version 2.0 (the "License"); you may 

6# not use this file except in compliance with the License. You may obtain 

7# a copy of the License at 

8# 

9# http://www.apache.org/licenses/LICENSE-2.0 

10# 

11# Unless required by applicable law or agreed to in writing, software 

12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

14# License for the specific language governing permissions and limitations 

15# under the License. 

16 

17"""Base Manager class. 

18 

19Managers are responsible for a certain aspect of the system. It is a logical 

20grouping of code relating to a portion of the system. In general other 

21components should be using the manager to make changes to the components that 

22it is responsible for. 

23 

24For example, other components that need to deal with volumes in some way, 

25should do so by calling methods on the VolumeManager instead of directly 

26changing fields in the database. This allows us to keep all of the code 

27relating to volumes in the same place. 

28 

29We have adopted a basic strategy of Smart managers and dumb data, which means 

30rather than attaching methods to data objects, components should call manager 

31methods that act on the data. 

32 

33Methods on managers that can be executed locally should be called directly. If 

34a particular method must execute on a remote host, this should be done via rpc 

35to the service that wraps the manager 

36 

37Managers should be responsible for most of the db access, and 

38non-implementation specific data. Anything implementation specific that can't 

39be generalized should be done by the Driver. 

40 

41In general, we prefer to have one manager with multiple drivers for different 

42implementations, but sometimes it makes sense to have multiple managers. You 

43can think of it this way: Abstract different overall strategies at the manager 

44level(FlatNetwork vs VlanNetwork), and different implementations at the driver 

45level(LinuxNetDriver vs CiscoNetDriver). 

46 

47Managers will often provide methods for initial setup of a host or periodic 

48tasks to a wrapping service. 

49 

50This module provides Manager, a base class for managers. 

51 

52""" 

53 

54from oslo_service import periodic_task 

55 

56import nova.conf 

57import nova.db.main.api 

58from nova import profiler 

59from nova import rpc 

60 

61 

62CONF = nova.conf.CONF 

63 

64 

65class PeriodicTasks(periodic_task.PeriodicTasks): 

66 def __init__(self): 

67 super(PeriodicTasks, self).__init__(CONF) 

68 

69 

70class ManagerMeta(profiler.get_traced_meta(), type(PeriodicTasks)): 

71 """Metaclass to trace all children of a specific class. 

72 

73 This metaclass wraps every public method (not starting with _ or __) 

74 of the class using it. All children classes of the class using ManagerMeta 

75 will be profiled as well. 

76 

77 Adding this metaclass requires that the __trace_args__ attribute be added 

78 to the class we want to modify. That attribute is a dictionary 

79 with one mandatory key: "name". "name" defines the name 

80 of the action to be traced (for example, wsgi, rpc, db). 

81 

82 The OSprofiler-based tracing, although, will only happen if profiler 

83 instance was initiated somewhere before in the thread, that can only happen 

84 if profiling is enabled in nova.conf and the API call to Nova API contained 

85 specific headers. 

86 """ 

87 

88 

89class Manager(PeriodicTasks, metaclass=ManagerMeta): 

90 __trace_args__ = {"name": "rpc"} 

91 

92 def __init__(self, host=None, service_name='undefined'): 

93 if not host: 

94 host = CONF.host 

95 self.host = host 

96 self.backdoor_port = None 

97 self.service_name = service_name 

98 self.notifier = rpc.get_notifier(self.service_name, self.host) 

99 self.additional_endpoints = [] 

100 super(Manager, self).__init__() 

101 

102 def periodic_tasks(self, context, raise_on_error=False): 

103 """Tasks to be run at a periodic interval.""" 

104 return self.run_periodic_tasks(context, raise_on_error=raise_on_error) 

105 

106 def init_host(self, service_ref): 

107 """Hook to do additional manager initialization when one requests 

108 the service be started. This is called before any service record 

109 is created, but if one already exists for this service, it is 

110 provided. 

111 

112 Child classes should override this method. 

113 

114 :param service_ref: An objects.Service if one exists, else None. 

115 """ 

116 pass 

117 

118 def cleanup_host(self): 

119 """Hook to do cleanup work when the service shuts down. 

120 

121 Child classes should override this method. 

122 """ 

123 pass 

124 

125 def pre_start_hook(self, service_ref): 

126 """Hook to provide the manager the ability to do additional 

127 start-up work before any RPC queues/consumers are created. This is 

128 called after other initialization has succeeded and a service 

129 record is created. 

130 

131 Child classes should override this method. 

132 

133 :param service_ref: The nova.objects.Service for this 

134 """ 

135 pass 

136 

137 def post_start_hook(self): 

138 """Hook to provide the manager the ability to do additional 

139 start-up work immediately after a service creates RPC consumers 

140 and starts 'running'. 

141 

142 Child classes should override this method. 

143 """ 

144 pass 

145 

146 def reset(self): 

147 """Hook called on SIGHUP to signal the manager to re-read any 

148 dynamic configuration or do any reconfiguration tasks. 

149 """ 

150 pass