Package flumotion :: Package worker :: Module main
[hide private]

Source Code for Module flumotion.worker.main

  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 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  import os 
 23  import sys 
 24   
 25  from twisted.internet import reactor 
 26   
 27  from flumotion.configure import configure 
 28  from flumotion.common import log, errors 
 29  from flumotion.common import connection 
 30  from flumotion.common.options import OptionGroup, OptionParser 
 31  from flumotion.common.process import startup 
 32  from flumotion.worker import worker, config 
 33  from flumotion.twisted import pb 
 34   
 35  __version__ = "$Rev: 6988 $" 
 36   
 37   
38 -def _createParser():
39 parser = OptionParser(domain="flumotion-worker") 40 41 group = OptionGroup(parser, "worker options") 42 group.add_option('-H', '--host', 43 action="store", type="string", dest="host", 44 help="manager host to connect to [default localhost]") 45 group.add_option('-P', '--port', 46 action="store", type="int", dest="port", 47 help="manager port to connect to " \ 48 "[default %d (ssl) or %d (tcp)]" % ( 49 configure.defaultSSLManagerPort, 50 configure.defaultTCPManagerPort)) 51 group.add_option('-T', '--transport', 52 action="store", type="string", dest="transport", 53 help="transport protocol to use (tcp/ssl) [default ssl]") 54 group.add_option('-n', '--name', 55 action="store", type="string", dest="name", 56 help="worker name to use in the manager") 57 group.add_option('-s', '--service-name', 58 action="store", type="string", dest="serviceName", 59 help="name to use for log and pid files " 60 "when run as a daemon") 61 group.add_option('-D', '--daemonize', 62 action="store_true", dest="daemonize", 63 help="run in background as a daemon") 64 group.add_option('', '--daemonize-to', 65 action="store", dest="daemonizeTo", 66 help="what directory to run from when daemonizing") 67 68 parser.add_option('-L', '--logdir', 69 action="store", dest="logdir", 70 help="flumotion log directory (default: %s)" % 71 configure.logdir) 72 parser.add_option('-R', '--rundir', 73 action="store", dest="rundir", 74 help="flumotion run directory (default: %s)" % 75 configure.rundir) 76 77 group.add_option('-u', '--username', 78 action="store", type="string", dest="username", 79 default="", 80 help="username to use") 81 group.add_option('-p', '--password', 82 action="store", type="string", dest="password", 83 default="", 84 help="password to use") 85 86 group.add_option('-F', '--feederports', 87 action="store", type="string", dest="feederports", 88 help="range of feeder ports to use") 89 group.add_option('', '--random-feederports', 90 action="store_true", 91 dest="randomFeederports", 92 help="Use randomly available feeder ports") 93 94 parser.add_option_group(group) 95 96 return parser
97
98 -def _readConfig(workerFile, options):
99 # modifies options dict in-place 100 log.info('worker', 'Reading configuration from %s' % workerFile) 101 try: 102 cfg = config.WorkerConfigXML(workerFile) 103 except config.ConfigError, value: 104 raise errors.FatalError( 105 "Could not load configuration from %s: %s" % ( 106 workerFile, value)) 107 except IOError, e: 108 raise errors.FatalError( 109 "Could not load configuration from %s: %s" % ( 110 workerFile, e.strerror)) 111 112 # now copy over stuff from config that is not set yet 113 if not options.name and cfg.name: 114 log.debug('worker', 'Setting worker name %s' % cfg.name) 115 options.name = cfg.name 116 117 # manager 118 if not options.host and cfg.manager.host: 119 options.host = cfg.manager.host 120 log.debug('worker', 'Setting manager host to %s' % options.host) 121 if not options.port and cfg.manager.port: 122 options.port = cfg.manager.port 123 log.debug('worker', 'Setting manager port to %s' % options.port) 124 if not options.transport and cfg.manager.transport: 125 options.transport = cfg.manager.transport 126 log.debug('worker', 'Setting manager transport to %s' % 127 options.transport) 128 129 # authentication 130 if not options.username and cfg.authentication.username: 131 options.username = cfg.authentication.username 132 log.debug('worker', 'Setting username %s' % options.username) 133 if not options.password and cfg.authentication.password: 134 options.password = cfg.authentication.password 135 log.debug('worker', 136 'Setting password [%s]' % ("*" * len(options.password))) 137 138 # feederports: list of allowed ports 139 # XML could specify it as empty, meaning "don't use any" 140 if not options.feederports and cfg.feederports is not None: 141 options.feederports = cfg.feederports 142 if options.randomFeederports is None: 143 options.randomFeederports = cfg.randomFeederports 144 if options.randomFeederports: 145 options.feederports = None 146 log.debug('worker', 'Using random feederports') 147 if options.feederports is not None: 148 log.debug('worker', 'Using feederports %r' % options.feederports) 149 150 # general 151 # command-line debug > environment debug > config file debug 152 if not options.debug and cfg.fludebug \ 153 and not os.environ.has_key('FLU_DEBUG'): 154 options.debug = cfg.fludebug
155
156 -def main(args):
157 parser = _createParser() 158 log.debug('worker', 'Parsing arguments (%r)' % ', '.join(args)) 159 options, args = parser.parse_args(args) 160 161 # Force options down configure's throat 162 for d in ['logdir', 'rundir']: 163 o = getattr(options, d, None) 164 if o: 165 log.debug('worker', 'Setting configure.%s to %s' % (d, o)) 166 setattr(configure, d, o) 167 168 # translate feederports string to range 169 if options.feederports: 170 if not '-' in options.feederports: 171 raise errors.OptionError("feederports '%s' does not contain '-'" % 172 options.feederports) 173 (lower, upper) = options.feederports.split('-') 174 options.feederports = range(int(lower), int(upper) + 1) 175 176 # check if a config file was specified; if so, parse config and copy over 177 if len(args) > 1: 178 workerFile = args[1] 179 _readConfig(workerFile, options) 180 181 # set default values for all unset options 182 if not options.host: 183 options.host = 'localhost' 184 if not options.transport: 185 options.transport = 'ssl' 186 if not options.port: 187 if options.transport == "tcp": 188 options.port = configure.defaultTCPManagerPort 189 elif options.transport == "ssl": 190 options.port = configure.defaultSSLManagerPort 191 192 # set a default name if none is given 193 if not options.name: 194 if options.host == 'localhost': 195 options.name = 'localhost' 196 log.debug('worker', 'Setting worker name localhost') 197 else: 198 import socket 199 options.name = socket.gethostname() 200 log.debug('worker', 'Setting worker name %s (from hostname)' % 201 options.name) 202 203 if options.feederports is None and not options.randomFeederports: 204 options.feederports = configure.defaultGstPortRange 205 log.debug('worker', 'Using default feederports %r' % 206 options.feederports) 207 208 # check for wrong options/arguments 209 if not options.transport in ['ssl', 'tcp']: 210 sys.stderr.write('ERROR: wrong transport %s, must be ssl or tcp\n' % 211 options.transport) 212 return 1 213 214 # reset FLU_DEBUG which could be different after parsing XML file 215 if options.debug: 216 log.setFluDebug(options.debug) 217 218 if options.daemonizeTo and not options.daemonize: 219 sys.stderr.write( 220 'ERROR: --daemonize-to can only be used with -D/--daemonize.\n') 221 return 1 222 223 if options.serviceName and not options.daemonize: 224 sys.stderr.write( 225 'ERROR: --service-name can only be used with -D/--daemonize.\n') 226 return 1 227 228 brain = worker.WorkerBrain(options) 229 230 # Now bind and listen to our unix and tcp sockets 231 if not brain.listen(): 232 sys.stderr.write('ERROR: Failed to listen on worker ports.\n') 233 return 1 234 235 name = options.name 236 if options.daemonize: 237 if options.serviceName: 238 name = options.serviceName 239 if not options.daemonizeTo: 240 options.daemonizeTo = "/" 241 242 startup("worker", name, options.daemonize, options.daemonizeTo) 243 244 log.debug('worker', 'Running Flumotion version %s' % 245 configure.version) 246 import twisted.copyright 247 log.debug('worker', 'Running against Twisted version %s' % 248 twisted.copyright.version) 249 250 # register all package paths (FIXME: this should go away when 251 # components come from manager) 252 from flumotion.common import setup 253 setup.setupPackagePath() 254 255 # FIXME: why address='localhost' ? 256 authenticator = pb.Authenticator(username=options.username, 257 password=options.password, 258 address='localhost', 259 avatarId=options.name) 260 info = connection.PBConnectionInfo(options.host, options.port, 261 options.transport == "ssl", 262 authenticator) 263 brain.login(info) 264 265 log.info('worker', 266 'Connecting to manager %s using %s' % (info, 267 options.transport.upper())) 268 269 270 # go into the reactor main loop 271 reactor.run() 272 273 return 0
274