Trees | Indices | Help |
---|
|
1 # -*- Mode: Python -*- 2 # vi:si:et:sw=4:sts=4:ts=4 3 4 # Flumotion - a streaming media server 5 # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 6 # Copyright (C) 2010,2011 Flumotion Services, S.A. 7 # All rights reserved. 8 # 9 # This file may be distributed and/or modified under the terms of 10 # the GNU Lesser General Public License version 2.1 as published by 11 # the Free Software Foundation. 12 # This file is distributed without any warranty; without even the implied 13 # warranty of merchantability or fitness for a particular purpose. 14 # See "LICENSE.LGPL" in the source distribution for more information. 15 # 16 # Headers in this file shall remain intact. 17 18 """ 19 component commands 20 """ 21 from twisted.internet import defer 22 23 from flumotion.admin.command import common 24 from flumotion.common import errors, planet, log 25 from flumotion.monitor.nagios import util 26 from flumotion.common.planet import moods 27 28 __version__ = "$Rev: 6562 $" 29 3032 description = "Delete a component." 3352 53 d.addCallback(cb) 54 d.addErrback(eb) 55 56 return d 57 5835 if not self.parentCommand.componentId: 36 common.errorRaise("Please specify a component id " 37 "with 'component -i [component-id]'") 38 39 d = self.getRootCommand().medium.callRemote('deleteComponent', 40 self.parentCommand.componentState) 41 42 def cb(result): 43 self.stdout.write("Deleted component.\n")44 45 def eb(failure): 46 if failure.check(errors.ComponentMoodError, 47 errors.BusyComponentError): 48 common.errorRaise("Component '%s' is in the wrong mood." % 49 self.parentCommand.componentId) 50 else: 51 common.errorRaise(log.getFailureMessage(failure))60 usage = "[method-name] [arguments]" 61 summary = "invoke a method on a component" 62 description = """Invoke a method on a component. 63 %s 64 For a list of methods that can be invoked, see the component's medium class 65 and its remote_* methods. 66 67 Examples: getConfig, setFluDebug""" % common.ARGUMENTS_DESCRIPTION 68114 115 d.addCallback(cb) 116 d.addErrback(eb) 117 118 return d 119 12070 self.parser.add_option('-r', '--raw-output', 71 action="store_true", dest="rawOutput", 72 help="do not pretty print the output")7375 self.rawOutput = options.rawOutput7678 if not self.parentCommand.componentId: 79 common.errorRaise("Please specify a component id " 80 "with 'component -i [component-id]'") 81 82 try: 83 methodName = args[0] 84 except IndexError: 85 common.errorRaise('Please specify a method name to invoke.') 86 if len(args) > 1: 87 args = common.parseTypedArgs(args[1], args[2:]) 88 if args is None: 89 common.errorRaise('Could not parse arguments.') 90 else: 91 args = [] 92 93 p = self.parentCommand 94 d = self.getRootCommand().medium.componentCallRemote( 95 self.parentCommand.componentState, methodName, *args) 96 97 def cb(result): 98 if self.rawOutput: 99 self.stdout.write(str(result)) 100 else: 101 import pprint 102 self.stdout.write("Invoking '%s' on '%s' returned:\n%s\n" % ( 103 methodName, p.componentId, pprint.pformat(result)))104 105 def eb(failure): 106 if failure.check(errors.NoMethodError): 107 common.errorRaise("No method '%s' on component '%s'." % ( 108 methodName, p.componentId)) 109 elif failure.check(errors.SleepingComponentError): 110 common.errorRaise( 111 "Component '%s' is sleeping." % p.componentId) 112 else: 113 common.errorRaise(log.getFailureMessage(failure))122 description = "List components." 123137 138125 p = self.parentCommand 126 a = p.planetState.get('atmosphere') 127 if a.get('components'): 128 self.stdout.write('atmosphere:\n') 129 for c in a.get('components'): 130 self.stdout.write(' ' + c.get('name') + '\n') 131 132 for f in p.planetState.get('flows'): 133 if f.get('components'): 134 self.stdout.write('%s flow:\n' % f.get('name')) 135 for c in f.get('components'): 136 self.stdout.write(' ' + c.get('name') + '\n')140 description = "List components with types and worker hosts." 141157 158143 p = self.parentCommand 144 a = p.planetState.get('atmosphere') 145 s = p.workerHeavenState 146 workers = s.get('workers') 147 a_comps = a.get('components') 148 if a_comps: 149 self.stdout.write('atmosphere:\n') 150 self.parentCommand.print_components(a_comps, workers) 151 152 for f in p.planetState.get('flows'): 153 f_comps = f.get('components') 154 if f_comps: 155 self.stdout.write('%s flow:\n' % f.get('name')) 156 self.parentCommand.print_components(f_comps, workers)160 description = """List a component and its upstream components along 161 with types and worker hosts.""" 162198 199164 avatars = [] 165 for flow in eaters_dic.keys(): 166 comps = eaters_dic[flow] 167 for c in comps: 168 (name, what) = c[0].split(':') 169 avatars.append('/%s/%s' % (flow, name)) 170 return avatars171173 p = self.parentCommand 174 s = p.workerHeavenState 175 workers = s.get('workers') 176 177 if not p.componentId: 178 common.errorRaise("Please specify a component id " 179 "with 'component -i [component-id]'") 180 181 eaters = p.componentState.get('config').get('eater', {}) 182 eaters_id = self.get_eaters_ids(eaters) 183 comps = [p.componentState] 184 while len(eaters_id) > 0: 185 eaters = {} 186 for i in eaters_id: 187 try: 188 compState = util.findComponent(p.planetState, i) 189 comps.append(compState) 190 eaters.update(compState.get('config').get('eater', {})) 191 except Exception, e: 192 self.debug(log.getExceptionMessage(e)) 193 common.errorRaise("Error retrieving component '%s'" % i) 194 eaters_id = self.get_eaters_ids(eaters) 195 196 self.stdout.write('Upstream Components:\n') 197 self.parentCommand.print_components(comps, workers)201 description = """List a component and its downstream components along 202 with types and worker hosts.""" 203 204 components = [] 205245 246207 p = self.parentCommand 208 s = p.workerHeavenState 209 workers = s.get('workers') 210 211 if not p.componentId: 212 common.errorRaise("Please specify a component id " 213 "with 'component -i [component-id]'") 214 215 self.stdout.write('Downstream Components:\n') 216 217 d = defer.maybeDeferred(self.getUIState, p.componentState) 218 d.addCallback(self.parentCommand.print_components, workers) 219 return d220222 p = self.parentCommand 223 admin = p.parentCommand.medium 224 225 self.components.append(state) 226 d = admin.componentCallRemote(state, 'getUIState') 227 d.addCallback(self.gotUIState) 228 return d229231 p = self.parentCommand 232 233 dList = [] 234 for f in state.get('feeders'): 235 for c in f['clients']: 236 feeder_id = c['client-id'].split(':')[0] 237 compState = util.findComponent(p.planetState, feeder_id) 238 if compState is None or compState in self.components: 239 continue 240 d = defer.maybeDeferred(self.getUIState, compState) 241 dList.append(d) 242 d = defer.DeferredList(dList) 243 d.addCallback(lambda result: self.components) 244 return d248 description = "Check the mood of a component." 249260 261251 if not self.parentCommand.componentId: 252 common.errorRaise("Please specify a component id " 253 "with 'component -i [component-id]'") 254 255 p = self.parentCommand 256 moodValue = p.componentState.get('mood') 257 moodName = planet.moods.get(moodValue).name 258 self.stdout.write("Component '%s' is %s.\n" % (p.componentId, 259 moodName))263 description = "Get a property of a component." 264 name = 'get' 265284 285 296 297 # FIXME: why is this called property when it really is about ui state ? 298 299267 if not args: 268 return common.errorReturn('Please specify a property to get.') 269 270 self._propertyName = args[0] 271 272 return common.AdminCommand.do(self, args)273275 u = self.parentCommand.uiState 276 name = self._propertyName 277 278 if not u.hasKey(name): 279 common.errorRaise("Component '%s' does not have property '%s'." % ( 280 self.parentCommand.parentCommand.componentId, name)) 281 282 self.stdout.write("Property '%s' is '%r'.\n" % ( 283 name, u.get(name)))301 """ 302 @param uiState: the ui state of the component; set after logging in. 303 """ 304 305 description = "Act on properties of a component." 306 307 subCommandClasses = [PropertyGet, PropertyList] 308330310 if not self.parentCommand.componentId: 311 common.errorRaise("Please specify a component id " 312 "with 'component -i [component-id]'") 313 314 # call our callback after connecting 315 d = self.getRootCommand().loginDeferred 316 d.addCallback(self._callback) 317 d.addErrback(self._errback)318 323 324 componentCommand = self.parentCommand 325 model = componentCommand.parentCommand.medium 326 d = model.componentCallRemote( 327 componentCommand.componentState, 'getUIState') 328 d.addCallback(getUIStateCb) 329 return d332 failure.trap(errors.SleepingComponentError) 333 common.errorRaise("Component '%s' is sleeping." % 334 self.parentCommand.componentId)335 336338 description = "Start a component." 339363 364 d.addCallback(cb) 365 d.addErrback(eb) 366 367 return d 368 369341 if not self.parentCommand.componentId: 342 common.errorRaise("Please specify a component id " 343 "with 'component -i [component-id]'") 344 345 p = self.parentCommand 346 moodValue = p.componentState.get('mood') 347 if moodValue == moods.happy.value: 348 self.stdout.write("Component is already happy.\n") 349 return 0 350 351 d = self.getRootCommand().medium.callRemote('componentStart', 352 self.parentCommand.componentState) 353 354 def cb(result): 355 self.stdout.write("Started component.\n")356 357 def eb(failure): 358 if failure.trap(errors.ComponentMoodError): 359 common.errorRaise("Component '%s' is in the wrong mood." % 360 self.parentCommand.componentId) 361 else: 362 common.errorRaise(log.getFailureMessage(failure))371 description = "Stop a component." 372396 397 d.addCallback(cb) 398 d.addErrback(eb) 399 400 return d 401 402374 if not self.parentCommand.componentId: 375 common.errorRaise("Please specify a component id " 376 "with 'component -i [component-id]'") 377 378 p = self.parentCommand 379 moodValue = p.componentState.get('mood') 380 if moodValue == moods.sleeping.value: 381 self.stdout.write("Component is already sleeping.\n") 382 return 0 383 384 d = self.getRootCommand().medium.callRemote('componentStop', 385 self.parentCommand.componentState) 386 387 def cb(result): 388 self.stdout.write("Stopped component.\n")389 390 def eb(failure): 391 if failure.trap(errors.ComponentMoodError): 392 common.errorRaise("Component '%s' is in the wrong mood." % 393 self.parentCommand.componentId) 394 else: 395 common.errorRaise(log.getFailureMessage(failure))404 """ 405 @ivar componentId: the component id, passed as an argument 406 @ivar componentState: the component state; set when logged in to manager. 407 @type componentState: L{flumotion.common.state.AdminComponentState} 408 @ivar planetState: the planet state; set when logged in to manager. 409 @type planetState: L{flumotion.common.state.AdminPlanetState} 410 """ 411 description = "Act on a component." 412 usage = "-i [component id]" 413 414 subCommandClasses = [Delete, Invoke, List, DetailedList, UpstreamList, 415 DownstreamList, Mood, Property, Start, Stop] 416 417 componentId = None 418 componentState = None 419 planetState = None 420 workerHeavenState = None 421462 463 def gotWorkerHeavenStateCb(result): 464 self.workerHeavenState = result 465 466 d.addCallback(gotPlanetStateCb) 467 d.addCallback(getWorkerHeavenStateCb) 468 d.addCallback(gotWorkerHeavenStateCb) 469 return d 470423 self.parser.add_option('-i', '--component-id', 424 action="store", dest="componentId", 425 help="component id of the component") 426 self.parser.add_option('-e', '--extra-attrs', 427 action="store", dest="extraAttributes", default="", 428 help="comma-separated extra attributes for the component list")429431 self.componentId = options.componentId 432 self.extraAttributes = options.extraAttributes.split(",") 433 # call our callback after connecting 434 self.getRootCommand().loginDeferred.addCallback(self._callback)435437 d = self.parentCommand.medium.callRemote('getPlanetState') 438 439 def gotPlanetStateCb(result): 440 self.planetState = result 441 self.debug('gotPlanetStateCb') 442 443 # only get componentState if we got passed an argument for it 444 if not self.componentId: 445 return 446 447 try: 448 self.componentState = util.findComponent(result, 449 self.componentId) 450 except Exception, e: 451 self.debug(log.getExceptionMessage(e)) 452 common.errorRaise("Invalid component id '%s'" % 453 self.componentId) 454 self.debug('gotPlanetStateCb') 455 if not self.componentState: 456 common.errorRaise('Could not find component %s' % 457 self.componentId)458 459 def getWorkerHeavenStateCb(result): 460 d = self.parentCommand.medium.callRemote('getWorkerHeavenState') 461 return d472 tab = 4 473 cols = [[c[i] for c in comps] for i in xrange(len(comps[0]))] 474 max_widths = [max(map(len, c)) for c in cols] 475 for c in comps: 476 s = " " 477 for i in xrange(len(c)): 478 width = "%d" % (max_widths[i] + tab) 479 s += ('%-' + width + "s") % c[i] 480 self.stdout.write(s + "\n")481483 comps = [] 484 for c in components: 485 workerName = c.get('workerName') 486 host = "unknown" 487 for w in workers: 488 if workerName == w.get('name'): 489 host = w.get('host') 490 break 491 moodName = planet.moods.get(c.get('mood')).name 492 componentAttrs = [c.get('name'), c.get('type'), host, moodName] 493 for attr in self.extraAttributes: 494 if c.hasKey(attr): 495 componentAttrs.append(str(c.get(attr))) 496 comps.append(componentAttrs) 497 self.pprint(comps)498
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Mon May 11 07:19:38 2015 | http://epydoc.sourceforge.net |