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