Coverage for manila/share/hook.py: 100%

61 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-02-18 22:19 +0000

1# Copyright (c) 2015 Mirantis, Inc. 

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""" 

17Module with hook interface for actions performed by share driver. 

18 

19All available hooks are placed in manila/share/hooks dir. 

20 

21Hooks are used by share services and can serve several use cases such as 

22any kind of notification and performing additional backend-specific actions. 

23""" 

24 

25import abc 

26 

27from oslo_config import cfg 

28from oslo_log import log 

29 

30from manila import context as ctxt 

31 

32 

33hook_options = [ 

34 cfg.BoolOpt( 

35 "enable_pre_hooks", 

36 default=False, 

37 help="Whether to enable pre hooks or not."), 

38 cfg.BoolOpt( 

39 "enable_post_hooks", 

40 default=False, 

41 help="Whether to enable post hooks or not."), 

42 cfg.BoolOpt( 

43 "enable_periodic_hooks", 

44 default=False, 

45 help="Whether to enable periodic hooks or not."), 

46 cfg.BoolOpt( 

47 "suppress_pre_hooks_errors", 

48 default=False, 

49 help="Whether to suppress pre hook errors (allow driver perform " 

50 "actions) or not."), 

51 cfg.BoolOpt( 

52 "suppress_post_hooks_errors", 

53 default=False, 

54 help="Whether to suppress post hook errors (allow driver's results " 

55 "to pass through) or not."), 

56 cfg.FloatOpt( 

57 "periodic_hooks_interval", 

58 default=300.0, 

59 help="Interval in seconds between execution of periodic hooks. " 

60 "Used when option 'enable_periodic_hooks' is set to True. " 

61 "Default is 300."), 

62] 

63 

64CONF = cfg.CONF 

65CONF.register_opts(hook_options) 

66LOG = log.getLogger(__name__) 

67 

68 

69class HookBase(metaclass=abc.ABCMeta): 

70 

71 def get_config_option(self, key): 

72 if self.configuration: 

73 return self.configuration.safe_get(key) 

74 return CONF.get(key) 

75 

76 def __init__(self, configuration, host): 

77 self.host = host 

78 self.configuration = configuration 

79 if self.configuration: 

80 self.configuration.append_config_values(hook_options) 

81 

82 self.pre_hooks_enabled = self.get_config_option("enable_pre_hooks") 

83 self.post_hooks_enabled = self.get_config_option("enable_post_hooks") 

84 self.periodic_hooks_enabled = self.get_config_option( 

85 "enable_periodic_hooks") 

86 self.suppress_pre_hooks_errors = self.get_config_option( 

87 "suppress_pre_hooks_errors") 

88 self.suppress_post_hooks_errors = self.get_config_option( 

89 "suppress_post_hooks_errors") 

90 

91 def execute_pre_hook(self, context=None, func_name=None, *args, **kwargs): 

92 """Hook called before driver's action.""" 

93 if not self.pre_hooks_enabled: 

94 return 

95 LOG.debug("Running 'pre hook'.") 

96 context = context or ctxt.get_admin_context() 

97 try: 

98 pre_data = self._execute_pre_hook( 

99 context=context, 

100 func_name=func_name, 

101 *args, **kwargs) 

102 except Exception as e: 

103 if self.suppress_pre_hooks_errors: 

104 LOG.warning("\nSuppressed exception in pre hook. %s\n", e) 

105 pre_data = e 

106 else: 

107 raise 

108 return pre_data 

109 

110 def execute_post_hook(self, context=None, func_name=None, 

111 pre_hook_data=None, driver_action_results=None, 

112 *args, **kwargs): 

113 """Hook called after driver's action.""" 

114 if not self.post_hooks_enabled: 

115 return 

116 LOG.debug("Running 'post hook'.") 

117 context = context or ctxt.get_admin_context() 

118 

119 try: 

120 post_data = self._execute_post_hook( 

121 context=context, 

122 func_name=func_name, 

123 pre_hook_data=pre_hook_data, 

124 driver_action_results=driver_action_results, 

125 *args, **kwargs) 

126 except Exception as e: 

127 if self.suppress_post_hooks_errors: 

128 LOG.warning( 

129 "\nSuppressed exception in post hook. %s\n", e) 

130 post_data = e 

131 else: 

132 raise 

133 return post_data 

134 

135 def execute_periodic_hook(self, context, periodic_hook_data, 

136 *args, **kwargs): 

137 """Hook called on periodic basis.""" 

138 if not self.periodic_hooks_enabled: 

139 return 

140 LOG.debug("Running 'periodic hook'.") 

141 context = context or ctxt.get_admin_context() 

142 return self._execute_periodic_hook( 

143 context, periodic_hook_data, *args, **kwargs) 

144 

145 @abc.abstractmethod 

146 def _execute_pre_hook(self, context, func_name, *args, **kwargs): 

147 """Redefine this method for pre hook action.""" 

148 

149 @abc.abstractmethod 

150 def _execute_post_hook(self, context, func_name, pre_hook_data, 

151 driver_action_results, *args, **kwargs): 

152 """Redefine this method for post hook action.""" 

153 

154 @abc.abstractmethod 

155 def _execute_periodic_hook(self, context, periodic_hook_data, 

156 *args, **kwargs): 

157 """Redefine this method for periodic hook action."""