1 """
2 Class that implements the common functionality for executing hooks before and
3 after the running of the solver
4 """
5 from optparse import OptionGroup
6 from PyFoam.ThirdParty.six.moves import configparser
7
8 from PyFoam import configuration
9 from PyFoam.Error import FatalErrorPyFoamException
10
11 from PyFoam.ThirdParty.six import print_,iteritems
12
13 import traceback
14
15 import sys
16
18 """ The class that runs the hooks
19 """
20
21 - def addOptions(self):
22 grp=OptionGroup(self.parser,
23 "Pre- and Postrun hooks",
24 "These options control the hooks that are either specified in the 'LocalConfigPyFoam' of the case or other config files (for a system-wide configuration)")
25 self.parser.add_option_group(grp)
26
27 grp.add_option("--disable-pre-hooks",
28 action="store_false",
29 dest="runPreHook",
30 default=True,
31 help="Disable running of hooks before the solver")
32 grp.add_option("--disable-post-hooks",
33 action="store_false",
34 dest="runPostHook",
35 default=True,
36 help="Disable running of hooks after the solver")
37 grp.add_option("--disable-all-hooks",
38 action="store_true",
39 dest="disableAllHooks",
40 default=False,
41 help="Disable running of hooks before and after the solver")
42 grp.add_option("--verbose-hooks",
43 action="store_true",
44 dest="verboseHooks",
45 default=False,
46 help="Be more informative about what is going on")
47 grp.add_option("--list-hooks",
48 action="store_true",
49 dest="listHooks",
50 default=False,
51 help="List the installed hooks")
52 grp.add_option("--hook-errors-are-fatal",
53 action="store_true",
54 dest="hookErrorsFatal",
55 default=False,
56 help="If there are problems with the hooks then execution of the runner stops")
57
58 - def hookmessage(self,*args):
59 if self.opts.verboseHooks:
60 for a in args:
61 print_(a,end="")
62 print_()
63
64 - def stopExecutionOnHookError(self,spec=False):
65 if spec or self.opts.hookErrorsFatal:
66 self.error("Stopping because of error in hook")
67
68 - def runPreHooks(self):
69 """Run the hooks before the execution of the solver"""
70 if self.opts.runPreHook:
71 self.hookmessage("Running pre-hooks")
72 for h,spec in iteritems(self.preHookInstances):
73 self.executeHook(h,spec)
74 else:
75 self.hookmessage("Pre-hooks disabled")
76
77 - def runPostHooks(self):
78 """Run the hooks after the execution of the solver"""
79 if self.opts.runPostHook:
80 self.hookmessage("Running post-hooks")
81 for h,spec in iteritems(self.postHookInstances):
82 self.executeHook(h,spec)
83 else:
84 self.hookmessage("Post-hooks disabled")
85 pass
86
87 - def executeHook(self,name,hDict):
88 try:
89 passed=self.getData()["wallTime"]
90 except KeyError:
91 passed=0
92 if passed<hDict["minRunTime"]:
93 self.hookmessage("Skipping",name,"because passed time",
94 passed,"smaller than",hDict["minRunTime"])
95 return
96 self.hookmessage("Executing hook",name)
97 try:
98 hDict["instance"]()
99 except FatalErrorPyFoamException:
100 e = sys.exc_info()[1]
101
102 self.warning("Problem executing",name,":",e)
103 except Exception:
104 self.warning("Problem while executing",
105 name,":",traceback.format_exc())
106 self.stopExecutionOnHookError(hDict["stopOnError"])
107
108 - def prepareHooks(self):
109 """Prepare the hooks and output additional info if wanted"""
110 self.hookmessage("Preparing hooks")
111 if self.opts.disableAllHooks:
112 self.hookmessage("Disabling all hooks")
113 self.opts.runPreHook=False
114 self.opts.runPostHook=False
115
116 if self.opts.listHooks:
117 print_("Hooks to execute before run")
118 print_("---------------------------")
119 self.dumpHooks(self.getHooksWithPrefix("preRunHook"))
120 print_()
121 print_("Hooks to execute after run")
122 print_("--------------------------")
123 self.dumpHooks(self.getHooksWithPrefix("postRunHook"))
124
125 self.preHookInstances={}
126 self.postHookInstances={}
127
128 self.hookmessage("Creating pre-hooks")
129 if self.opts.runPreHook:
130 self.checkAndCreateHookInstances(
131 self.preHookInstances,
132 "preRunHook"
133 )
134 self.hookmessage("Creating post-hooks")
135 if self.opts.runPostHook:
136 self.checkAndCreateHookInstances(
137 self.postHookInstances,
138 "postRunHook"
139 )
140
141 - def checkAndCreateHookInstances(self,toDict,prefix):
142 for h in self.getHooksWithPrefix(prefix):
143 self.hookmessage("Checking",h)
144 if configuration().getboolean(h,"enabled",default=True):
145 subdict={}
146 mod=configuration().get(h,"module",default="")
147 if mod=="":
148 self.warning("No module specified for",h)
149 continue
150 subdict["minRunTime"]=configuration().getfloat(h,
151 "minRunTime",
152 default=-1)
153 subdict["stopOnError"]=configuration().getboolean(h,
154 "stopOnError",
155 default=False)
156 self.hookmessage("Trying to import",mod)
157 try:
158 try:
159 module=__import__(mod,globals(),locals(),["dummy"])
160 except ImportError:
161 e = sys.exc_info()[1]
162 self.hookmessage("ImportError:",e)
163 mod="PyFoam.Infrastructure.RunHooks."+mod
164 self.hookmessage("Trying to import",mod)
165 try:
166 module=__import__(mod,globals(),locals(),["dummy"])
167 except ImportError:
168 self.hookmessage("ImportError:",e)
169 self.warning("Could not import module",
170 mod.split(".")[-1],"for",h,
171 "(Tried",mod,"too)")
172 continue
173 except SyntaxError:
174 e = sys.exc_info()[1]
175 self.hookmessage("SyntaxError:",e)
176 self.warning("Syntax error when trying to import",mod)
177 continue
178 try:
179 theClass=getattr(module,mod.split(".")[-1])
180 except AttributeError:
181 e = sys.exc_info()[1]
182 self.hookmessage("AttributeError:",e)
183 self.hookmessage("Attributes:",dir(module))
184 self.warning("Class",mod.split(".")[-1],"missing form",
185 mod)
186 continue
187 try:
188 subdict["instance"]=theClass(self,h)
189 except Exception:
190 self.warning("Problem while creating instance of",
191 theClass,":",traceback.format_exc())
192 self.stopExecutionOnHookError(subdict["stopOnError"])
193 continue
194 toDict[h]=subdict
195 else:
196 self.hookmessage(h,"is disabled")
197
198 - def dumpHooks(self,lst):
199 for h in lst:
200 print_(h)
201 try:
202 print_(" enabled:",configuration().getboolean(h,
203 "enabled",
204 default=True))
205 print_(" module:",configuration().get(h,
206 "module"))
207 print_(" minRunTime:",configuration().getfloat(h,
208 "minRunTime",
209 default=0))
210 print_(" description:",configuration().get(h,
211 "description",
212 default="None"))
213 except configparser.NoOptionError:
214 self.error("Hook",h,"incompletely defined")
215
216 - def getHooksWithPrefix(self,prefix):
217 lst=[]
218 for h in configuration().sections():
219 if h.find(prefix+"_")==0:
220 lst.append(h)
221 return lst
222
223
224