1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import sys
17 import os
18 import logging
19 from getopt import getopt, GetoptError
20 from gofer import *
21 from gofer.pam import PAM
22 from gofer.agent import *
23 from gofer.agent.plugin import PluginLoader, Plugin
24 from gofer.agent.lock import Lock, LockFailed
25 from gofer.agent.config import Config, nvl
26 from gofer.agent.logutil import getLogger
27 from gofer.agent.rmi import Scheduler
28 from time import sleep
29 from threading import Thread
30
31 log = getLogger(__name__)
32 cfg = Config()
33
34
36 """
37 Run actions independently of main thread.
38 @ivar actions: A list of actions to run.
39 @type actions: [L{Action},..]
40 """
41
43 """
44 @param actions: A list of actions to run.
45 @type actions: [L{Action},..]
46 """
47 self.actions = actions
48 Thread.__init__(self, name='Actions')
49 self.setDaemon(True)
50
52 """
53 Run actions.
54 """
55 while True:
56 for action in self.actions:
57 action()
58 sleep(1)
59
60
62 """
63 Plugin property snapshot.
64 Used to track changes in plugin properties.
65 """
66 __getattr__ = dict.get
67
69 keys = []
70 for k,v in properties.items():
71 if self.get(k) != v:
72 keys.append(k)
73 return keys
74
75
77 """
78 Run actions independantly of main thread.
79 @ivar plugin: A plugin to monitor.
80 @type plugin: L{Plugin}
81 """
82
84 """
85 @param plugin: A plugin to monitor.
86 @type plugin: L{Plugin}
87 """
88 self.plugin = plugin
89 self.snapshot = Snapshot()
90 Thread.__init__(self, name='%s-monitor' % plugin.name)
91 self.setDaemon(True)
92
94 """
95 Monitor plugin attach/detach.
96 """
97 while True:
98 try:
99 self.update()
100 except:
101 log.exception('plugin %s', self.plugin.name)
102 sleep(1)
103
124
125
127 """
128 Gofer (main) agent.
129 Starts (2) threads. A thread to run actions and
130 another to monitor/update plugin sessions on the bus.
131 """
132
133 WAIT = None
134
142
143 - def start(self, block=True):
154
156 """
157 Start actions on enabled plugins.
158 @param plugins: A list of loaded plugins.
159 @type plugins: list
160 @return: The started action thread.
161 @rtype: L{ActionThread}
162 """
163 actions = []
164 for plugin in plugins:
165 actions.extend(plugin.actions)
166 actionThread = ActionThread(actions)
167 actionThread.start()
168 return actionThread
169
171 """
172 Start the RMI scheduler.
173 @param plugins: A list of loaded plugins.
174 @type plugins: list
175 @return: The started scheduler thread.
176 @rtype: L{Scheduler}
177 """
178 scheduler = Scheduler(plugins)
179 scheduler.start()
180 return scheduler
181
193
194
196 """
197 Agent lock ensure that agent only has single instance running.
198 @cvar PATH: The lock file absolute path.
199 @type PATH: str
200 """
201
202 PATH = '/var/run/%sd.pid' % NAME
203
206
207
228
231
233 """
234 Show usage.
235 """
236 s = []
237 s.append('\n%sd <options>' % NAME)
238 s.append(' -h, --help')
239 s.append(' Show help')
240 s.append(' -c, --console')
241 s.append(' Run in the foreground and not as a daemon.')
242 s.append(' default: 0')
243 s.append(' -p [seconds], --profile [seconds]')
244 s.append(' Run (foreground) and print code profiling statistics.')
245 s.append('\n')
246 print '\n'.join(s)
247
249 """
250 Daemon configuration.
251 """
252 pid = os.fork()
253 if pid == 0:
254 os.setsid()
255 os.chdir('/')
256 os.close(0)
257 os.close(1)
258 os.close(2)
259 dn = os.open('/dev/null', os.O_RDWR)
260 os.dup(dn)
261 os.dup(dn)
262 os.dup(dn)
263 else:
264 lock.setpid(pid)
265 os.waitpid(pid, os.WNOHANG)
266 os._exit(0)
267
269 """
270 Set logging levels based on configuration.
271 """
272 for p in nvl(cfg.logging, []):
273 level = cfg.logging[p]
274 if not level:
275 continue
276 try:
277 L = getattr(logging, level.upper())
278 logger = logging.getLogger(p)
279 logger.setLevel(L)
280 except:
281 pass
282
284 """
285 Code profiler using YAPPI
286 http://code.google.com/p/yappi
287 """
288 import yappi
289 yappi.start()
290 start(False)
291 yappi.stop()
292 for pstat in yappi.get_stats(yappi.SORTTYPE_TSUB):
293 print pstat
294
296 daemon = True
297 setupLogging()
298 try:
299 opts, args = getopt(sys.argv[1:], 'hcp:', ['help','console','prof'])
300 for opt,arg in opts:
301 if opt in ('-h', '--help'):
302 usage()
303 sys.exit(0)
304 if opt in ('-c', '--console'):
305 daemon = False
306 continue
307 if opt in ('-p', '--prof'):
308 __start = profile
309 Agent.WAIT = int(arg)
310 profile()
311 return
312 start(daemon)
313 except GetoptError, e:
314 print e
315 usage()
316
317 if __name__ == '__main__':
318 main()
319