Package flumotion :: Package admin :: Package command :: Module worker
[hide private]

Source Code for Module flumotion.admin.command.worker

  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  worker commands 
 20  """ 
 21   
 22  import os 
 23  import time 
 24   
 25  from gettext import gettext as _ 
 26   
 27  from flumotion.configure import configure 
 28  from flumotion.common import errors, log, i18n, messages 
 29  from flumotion.monitor.nagios import util 
 30   
 31  from flumotion.admin.command import common 
 32   
 33  __version__ = "$Rev: 6562 $" 
 34   
 35   
36 -class Invoke(common.AdminCommand):
37 usage = "[method-name] [arguments]" 38 summary = "invoke a method on a worker" 39 description = """Invoke a method on a worker. 40 %s 41 For a list of methods that can be invoked, see the worker's medium class 42 in flumotion.worker.medium and its remote_* methods. 43 44 Examples: getFeedServerPort, killJob, getComponents, getVersions 45 46 checkElements [ss] oggmux vorbisenc 47 48 checkImport s sys""" % common.ARGUMENTS_DESCRIPTION 49
50 - def doCallback(self, args):
51 workerName = self.parentCommand.options.name 52 if not workerName: 53 common.errorRaise('Please specify a worker name with --name.') 54 55 try: 56 methodName = args[0] 57 except IndexError: 58 common.errorRaise('Please specify a method name.') 59 60 if len(args) > 1: 61 args = common.parseTypedArgs(args[1], args[2:]) 62 if args is None: 63 common.errorRaise('Could not parse arguments.') 64 else: 65 args = [] 66 67 p = self.parentCommand 68 d = self.getRootCommand().medium.callRemote( 69 'workerCallRemote', workerName, methodName, *args) 70 71 def cb(result): 72 import pprint 73 self.stdout.write("Invoking '%s' on '%s' returned:\n%s\n" % ( 74 methodName, workerName, pprint.pformat(result)))
75 76 def eb(failure): 77 # FIXME 78 if failure.check(errors.NoMethodError): 79 common.errorRaise("No method '%s' on worker '%s'." % ( 80 methodName, workerName)) 81 elif failure.check(errors.SleepingComponentError): 82 common.errorRaise("Component '%s' is sleeping." % 83 p.componentId) 84 elif failure.check(errors.RemoteRunError): 85 common.errorRaise(log.getFailureMessage(failure)) 86 else: 87 common.errorRaise(log.getFailureMessage(failure))
88 89 d.addCallback(cb) 90 d.addErrback(eb) 91 92 return d 93 94
95 -class List(common.AdminCommand):
96 description = "List workers." 97
98 - def doCallback(self, args):
99 s = self.parentCommand.workerHeavenState 100 workers = s.get('workers') 101 if not workers: 102 self.stdout.write('No workers logged in.\n') 103 return 104 105 for worker in workers: 106 self.stdout.write('%s: %s\n' % ( 107 worker.get('name'), worker.get('host')))
108 109
110 -class Run(common.AdminCommand):
111 usage = "[module-name] [method-name] [arguments]" 112 summary = "run a method on a worker" 113 description = """Run a method on a worker 114 %s 115 Any method that the worker can import can be run. 116 This is useful for testing worker checks. 117 118 Examples: 119 120 flumotion.worker.checks.video checkTVCard s /dev/video0 121 122 flumotion.worker.checks.audio checkMixerTracks ssi alsasrc hw:0 2 123 """ % common.ARGUMENTS_DESCRIPTION 124
125 - def doCallback(self, args):
126 try: 127 moduleName = args[0] 128 except IndexError: 129 common.errorRaise('Please specify a module name to invoke from.') 130 try: 131 methodName = args[1] 132 except IndexError: 133 common.errorRaise('Please specify a method name.') 134 135 if len(args) > 2: 136 args = common.parseTypedArgs(args[2], args[3:]) 137 if args is None: 138 common.errorRaise('Could not parse arguments.') 139 else: 140 args = [] 141 142 p = self.parentCommand 143 workerName = p.options.name 144 d = self.getRootCommand().medium.callRemote( 145 'workerCallRemote', workerName, 'runFunction', 146 moduleName, methodName, *args) 147 148 def cb(result): 149 i18n.installGettext() 150 # handle some results specifically, like Result 151 self.stdout.write("Invoking '%s' on '%s' returned:\n" % 152 (methodName, workerName)) 153 import pprint 154 self.stdout.write("%s\n" % pprint.pformat(result)) 155 156 if isinstance(result, messages.Result): 157 _headings = { 158 messages.ERROR: _('Error'), 159 messages.WARNING: _('Warning'), 160 messages.INFO: _('Note'), 161 } 162 163 for m in result.messages: 164 translator = i18n.Translator() 165 localedir = os.path.join(configure.localedatadir, 'locale') 166 # FIXME: add locales as messages from domains come in 167 translator.addLocaleDir(configure.PACKAGE, localedir) 168 self.stdout.write('%s:\n' % _headings[m.level]) 169 self.stdout.write(translator.translate(m) + '\n') 170 if hasattr(m, 'timestamp'): 171 self.stdout.write(_("\nPosted on %s.\n") % 172 time.strftime("%c", time.localtime(m.timestamp))) 173 if m.debug: 174 self.stdout.write("DEBUG:\n%s\n" % m.debug) 175 176 if result.failed: 177 self.stdout.write('Result failed.\n') 178 else: 179 self.stdout.write('Result successful:\n%s\n' % 180 pprint.pformat(result.value))
181 182 def eb(failure): 183 if failure.check(errors.NoMethodError): 184 common.errorRaise("No method '%s' on worker '%s'." % ( 185 methodName, workerName)) 186 elif failure.check(errors.SleepingComponentError): 187 common.errorRaise("Component '%s' is sleeping." % 188 p.componentId) 189 elif failure.check(errors.RemoteRunError): 190 common.errorRaise(log.getFailureMessage(failure)) 191 else: 192 common.errorRaise(log.getFailureMessage(failure))
193 194 d.addCallback(cb) 195 d.addErrback(eb) 196 197 return d 198 199
200 -class Worker(util.LogCommand):
201 """ 202 @param workerHeavenState: the planet state; set when logged in to manager. 203 @type workerHeavenState: L{flumotion.common.state.WorkerHeavenState} 204 """ 205 description = "Act on workers." 206 207 subCommandClasses = [Invoke, List, Run] 208
209 - def addOptions(self):
210 self.parser.add_option('-n', '--name', 211 action="store", dest="name", 212 help="name of the component")
213
214 - def handleOptions(self, options):
215 # call our callback after connecting 216 self.getRootCommand().loginDeferred.addCallback(self._callback)
217
218 - def _callback(self, result):
219 d = self.parentCommand.medium.callRemote('getWorkerHeavenState') 220 221 def gotWorkerHeavenStateCb(result): 222 self.workerHeavenState = result
223 d.addCallback(gotWorkerHeavenStateCb) 224 return d
225