1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """command registry and command implementations"""
23
24 import os
25
26 from twisted.internet import defer
27
28 from flumotion.twisted.defer import defer_generator
29 from flumotion.admin.command import utils
30 from flumotion.common.planet import moods
31 from flumotion.common import errors, log, componentui, common
32
33 __all__ = ['commands']
34 __version__ = "$Rev: 6990 $"
35
36
37
43 return 'Command %r not found in the PATH.' % self.command
44
46 if os.sep in executable:
47 if os.access(os.path.abspath(executable), os.X_OK):
48 return os.path.abspath(executable)
49 elif os.getenv('PATH'):
50 for path in os.getenv('PATH').split(os.pathsep):
51 if os.access(os.path.join(path, executable), os.X_OK):
52 return os.path.join(path, executable)
53 raise CommandNotFoundException(executable)
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
71 d = utils.get_component_uistate(model, avatarId)
72 yield d
73 uistate = d.value()
74 if uistate:
75 if uistate.hasKey(propname):
76 print uistate.get(propname)
77 else:
78 print ('Component %s in flow %s has no property called %s'
79 % (avatarId[1], avatarId[0], propname))
80 quit()
81 do_getprop = defer_generator(do_getprop)
82
84 d = utils.get_component_uistate(model, avatarId)
85 yield d
86 uistate = d.value()
87 if uistate:
88 for k in uistate.keys():
89 print k
90 quit()
91 do_listprops = defer_generator(do_listprops)
92
94 d = model.callRemote('getPlanetState')
95 yield d
96 planet = d.value()
97
98 for f in planet.get('flows'):
99 print 'flow: %s' % f.get('name')
100 for c in f.get('components'):
101 print ' %s' % c.get('name')
102
103 a = planet.get('atmosphere')
104 print 'atmosphere: %s' % a.get('name')
105 for c in a.get('components'):
106 print ' %s' % c.get('name')
107
108 quit()
109 do_showplanet = defer_generator(do_showplanet)
110
126 do_getmood = defer_generator(do_getmood)
127
129 def show_uistate(k, v, indent=0):
130 if isinstance(v, list):
131 show_uistate(k, '<list>', indent)
132 for x in v:
133 show_uistate(None, x, indent+4)
134 elif isinstance(v, dict):
135 show_uistate(k, '<dict>', indent)
136 keys = v.keys()
137 keys.sort()
138 for k in keys:
139 show_uistate(k, v[k], indent+4)
140 elif isinstance(v, componentui.AdminComponentUIState):
141 show_uistate(k, '<uistate>', indent)
142 keys = v.keys()
143 keys.sort()
144 for k in keys:
145 show_uistate(k, v.get(k), indent+4)
146 else:
147 print '%s%s%s' % (' '*indent, k and k+': ' or '', v)
148
149 d = model.callRemote('getPlanetState')
150 yield d
151 planet = d.value()
152 c = utils.find_component(planet, avatarId)
153 if c:
154 print 'Component state:'
155 keys = c.keys()
156 keys.sort()
157 for k in keys:
158 print ' %s: %r' % (k, c.get(k))
159 d = utils.get_component_uistate(model, avatarId, c, quiet=True)
160 yield d
161 try:
162 ui = d.value()
163 if ui:
164 print
165 show_uistate('UI state', ui)
166 except Exception, e:
167 print 'Error while retrieving UI state:', \
168 log.getExceptionMessage(e)
169 quit()
170 do_showcomponent = defer_generator(do_showcomponent)
171
174
176 def _readFile(filename):
177 try:
178 f = open(filename)
179 contents = f.read()
180 f.close()
181 return contents
182 except OSError:
183 raise ParseException("Failed to read file %s" % (filename,))
184
185 def _do_parse_typed_args(spec, args):
186 accum = []
187 while spec:
188 argtype = spec.pop(0)
189 parsers = {'i': int, 's': str, 'b': common.strToBool,
190 'F': _readFile}
191 if argtype == ')':
192 return tuple(accum)
193 elif argtype == '(':
194 accum.append(_do_parse_typed_args(spec, args))
195 elif argtype == '}':
196 return dict(accum)
197 elif argtype == '{':
198 accum.append(_do_parse_typed_args(spec, args))
199 elif argtype == ']':
200 return accum
201 elif argtype == '[':
202 accum.append(_do_parse_typed_args(spec, args))
203 elif argtype not in parsers:
204 raise ParseException('Unknown argument type: %r'
205 % argtype)
206 else:
207 parser = parsers[argtype]
208 try:
209 arg = args.pop(0)
210 except IndexError:
211 raise ParseException('Missing argument of type %r'
212 % parser)
213 try:
214 accum.append(parser(arg))
215 except Exception, e:
216 raise ParseException('Failed to parse %s as %r: %s'
217 % (arg, parser, e))
218
219 spec = list(spec) + [')']
220 args = list(args)
221
222 try:
223 res = _do_parse_typed_args(spec, args)
224 except ParseException, e:
225 print e.args[0]
226 return None
227
228 if args:
229 print 'Left over arguments:', args
230 return None
231 else:
232 return res
233
234 -def do_invoke(model, quit, avatarId, methodName, *args):
264 do_invoke = defer_generator(do_invoke)
265
266 -def do_workerinvoke(model, quit, workerName, moduleName, methodName, *args):
267 if args:
268 args = _parse_typed_args(args[0], args[1:])
269 if args is None:
270 quit()
271 yield None
272
273 d = model.callRemote('workerCallRemote', workerName, 'runFunction',
274 moduleName, methodName, *args)
275 yield d
276
277 try:
278 v = d.value()
279 print "Invoke of %s on %s was successful." % (methodName, workerName)
280 print v
281 except errors.NoMethodError:
282 print "No method '%s' on component '%s'" % (methodName, workerName)
283
284 quit()
285 do_workerinvoke = defer_generator(do_workerinvoke)
286
288 if args:
289 args = _parse_typed_args(args[0], args[1:])
290 if args is None:
291 quit()
292 yield None
293
294 d = model.callRemote('workerCallRemote', workerName, methodName, *args)
295 yield d
296
297 try:
298 v = d.value()
299 print "Invoke of %s on %s was successful." % (methodName, workerName)
300 print v
301 except errors.NoMethodError:
302 print "No method '%s' on component '%s'" % (methodName, workerName)
303
304 quit()
305 do_workerremoteinvoke = defer_generator(do_workerremoteinvoke)
306
325 do_managerinvoke = defer_generator(do_managerinvoke)
326
328 print 'Loading configuration from file: %s' % confFile
329
330 f = open(confFile, 'r')
331 configurationXML = f.read()
332 f.close()
333
334 d = model.callRemote('loadConfiguration', configurationXML,
335 saveAs=saveAs)
336 yield d
337 d.value()
338 print 'Configuration loaded successfully.'
339 if saveAs:
340 print 'Additionally, the configuration XML was saved on the manager.'
341
342 quit()
343 do_loadconfiguration = defer_generator(do_loadconfiguration)
344
346 d = model.callRemote('getWorkerHeavenState')
347 yield d
348 whs = d.value()
349
350 for worker in whs.get('workers'):
351 print "%s: %s" % (worker.get('name'), worker.get('host'))
352 quit()
353 do_showworkers = defer_generator(do_showworkers)
354
360
361 - def stateSet(self, object, key, value):
362 if key == 'mood' and moods[value] in self._moodsFinal:
363 self.callback(moods[value])
364
365
366
368 """
369 @type action: a tuple of (actionName, remoteCall, moods, checkMoodFunc)
370 """
371 d = model.callRemote('getPlanetState')
372 yield d
373 planet = d.value()
374 components = []
375 if avatarPath[0] == 'flow':
376 flows = planet.get('flows')
377 flow_to_act = None
378 for f in flows:
379 if avatarPath[1] == f.get('name'):
380 flow_to_act = f
381 if flow_to_act == None:
382 print "The flow %s is not found." % avatarPath[1]
383 quit()
384 else:
385 components = flow_to_act.get('components')
386 elif avatarPath[0] == 'atmosphere':
387 components = planet.get('atmosphere').get('components')
388 elif avatarPath[0] == 'root':
389 flows = planet.get('flows')
390 for f in flows:
391 components = components + f.get('components')
392 components = components + planet.get('atmosphere').get('components')
393 else:
394 c = utils.find_component(planet, avatarPath[1:])
395 if c:
396 components.append(c)
397
398
399 if len(components) > 0:
400 def actionComponent(c):
401 if action[3](moods[c.get('mood')]):
402 return model.callRemote(action[1], c)
403 else:
404 print "Cannot %s component /%s/%s, it is in mood: %s." % (
405 action[0],
406 c.get("parent").get("name"), c.get("name"),
407 moods[c.get("mood")].name)
408 return None
409 dl = []
410 for comp in components:
411 actD = actionComponent(comp)
412
413 if actD:
414 dl.append(actD)
415 if action[2]:
416
417 dl.append(MoodListener(action[2], comp))
418 d = defer.DeferredList(dl)
419 yield d
420 d.value()
421 if avatarPath[0] == 'flow':
422 print "Components in flow now completed action %s." % action[0]
423 elif avatarPath[0] == 'atmosphere':
424 print "Components in atmosphere now completed action %s." % (
425 action[0],)
426 elif avatarPath[0] == 'root':
427 print "Components in / now completed action %s." % action[0]
428 else:
429 print "Component now completed action %s." % action[0]
430 quit()
431 do_avatar_action = defer_generator(do_avatar_action)
432
433 -def do_stop(model, quit, avatarPath):
434 return do_avatar_action(model, quit, avatarPath, ('stop', 'componentStop',
435 (moods.sleeping,), moods.can_stop))
436
438 return do_avatar_action(model, quit, avatarPath, ('start', 'componentStart',
439 (moods.happy, moods.sad), moods.can_start))
440
442 return do_avatar_action(model, quit, avatarPath, ('delete',
443 'deleteComponent', None, lambda m: not moods.can_stop(m)))
444
445 commands = (('getprop',
446 'gets a property on a component',
447 (('component-path', utils.avatarId),
448 ('property-name', str)),
449 do_getprop),
450 ('listprops',
451 'lists the properties a component has',
452 (('component-path', utils.avatarId),
453 ),
454 do_listprops),
455 ('showplanet',
456 'shows the flows, atmosphere, and components in the planet',
457 (),
458 do_showplanet),
459 ('getmood',
460 'gets the mood of a component',
461 (('component-path', utils.avatarId),
462 ),
463 do_getmood),
464 ('showcomponent',
465 'shows everything we know about a component',
466 (('component-path', utils.avatarId),
467 ),
468 do_showcomponent),
469 ('showworkers',
470 'shows all the workers that are logged into the manager',
471 (),
472 do_showworkers),
473 ('invoke',
474 'invoke a component method',
475 (('component-path', utils.avatarId),
476 ('method-name', str),
477 ('args', str, None, True)),
478 do_invoke),
479 ('workerinvoke',
480 'invoke an arbitrary function on a worker',
481 (('worker-name', str),
482 ('module-name', str),
483 ('method-name', str),
484 ('args', str, None, True)),
485 do_workerinvoke),
486 ('workerremoteinvoke',
487 'invoke a remote function on a manager',
488 (('method-name', str),
489 ('args', str, None, True)),
490 do_workerremoteinvoke),
491 ('managerinvoke',
492 'invoke a function on a manager',
493 (('method-name', str),
494 ('args', str, None, True)),
495 do_managerinvoke),
496 ('loadconfiguration',
497 'load configuration into the manager',
498 (('conf-file', str),
499 ('save-as', str, None),
500 ),
501 do_loadconfiguration),
502 ('stop',
503 'stops a component, flow or all flows',
504 (('path', utils.avatarPath),
505 ),
506 do_stop),
507 ('start',
508 'starts a componment, all components in a flow or all flows',
509 (('path', utils.avatarPath),
510 ),
511 do_start),
512 ('delete',
513 'deletes a component, all components in a flow or all flows',
514 (('path', utils.avatarPath),
515 ),
516 do_delete)
517 )
518