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$" 
 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
99 -def _readConfig(workerFile, options):
100 # modifies options dict in-place 101 log.info('worker', 'Reading configuration from %s' % workerFile) 102 try: 103 cfg = config.WorkerConfigXML(workerFile) 104 except config.ConfigError, value: 105 raise errors.FatalError( 106 "Could not load configuration from %s: %s" % ( 107 workerFile, value)) 108 except IOError, e: 109 raise errors.FatalError( 110 "Could not load configuration from %s: %s" % ( 111 workerFile, e.strerror)) 112 113 # now copy over stuff from config that is not set yet 114 if not options.name and cfg.name: 115 log.debug('worker', 'Setting worker name %s' % cfg.name) 116 options.name = cfg.name 117 118 # manager 119 if not options.host and cfg.manager.host: 120 options.host = cfg.manager.host 121 log.debug('worker', 'Setting manager host to %s' % options.host) 122 if not options.port and cfg.manager.port: 123 options.port = cfg.manager.port 124 log.debug('worker', 'Setting manager port to %s' % options.port) 125 if not options.transport and cfg.manager.transport: 126 options.transport = cfg.manager.transport 127 log.debug('worker', 'Setting manager transport to %s' % 128 options.transport) 129 130 # authentication 131 if not options.username and cfg.authentication.username: 132 options.username = cfg.authentication.username 133 log.debug('worker', 'Setting username %s' % options.username) 134 if not options.password and cfg.authentication.password: 135 options.password = cfg.authentication.password 136 log.debug('worker', 137 'Setting password [%s]' % ("*" * len(options.password))) 138 139 # feederports: list of allowed ports 140 # XML could specify it as empty, meaning "don't use any" 141 if not options.feederports and cfg.feederports is not None: 142 options.feederports = cfg.feederports 143 if options.randomFeederports is None: 144 options.randomFeederports = cfg.randomFeederports 145 if options.randomFeederports: 146 options.feederports = None 147 log.debug('worker', 'Using random feederports') 148 if options.feederports is not None: 149 log.debug('worker', 'Using feederports %r' % options.feederports) 150 151 # general 152 # command-line debug > environment debug > config file debug 153 if not options.debug and cfg.fludebug \ 154 and not 'FLU_DEBUG' in os.environ: 155 options.debug = cfg.fludebug
156 157
158 -def main(args):
159 parser = _createParser() 160 log.debug('worker', 'Parsing arguments (%r)' % ', '.join(args)) 161 options, args = parser.parse_args(args) 162 163 # Force options down configure's throat 164 for d in ['logdir', 'rundir']: 165 o = getattr(options, d, None) 166 if o: 167 log.debug('worker', 'Setting configure.%s to %s' % (d, o)) 168 setattr(configure, d, o) 169 170 # translate feederports string to range 171 if options.feederports: 172 if not '-' in options.feederports: 173 raise errors.OptionError("feederports '%s' does not contain '-'" % 174 options.feederports) 175 (lower, upper) = options.feederports.split('-') 176 options.feederports = range(int(lower), int(upper) + 1) 177 178 # check if a config file was specified; if so, parse config and copy over 179 if len(args) > 1: 180 workerFile = args[1] 181 _readConfig(workerFile, options) 182 183 # set default values for all unset options 184 if not options.host: 185 options.host = 'localhost' 186 if not options.transport: 187 options.transport = 'ssl' 188 if not options.port: 189 if options.transport == "tcp": 190 options.port = configure.defaultTCPManagerPort 191 elif options.transport == "ssl": 192 options.port = configure.defaultSSLManagerPort 193 194 # set a default name if none is given 195 if not options.name: 196 if options.host == 'localhost': 197 options.name = 'localhost' 198 log.debug('worker', 'Setting worker name localhost') 199 else: 200 import socket 201 options.name = socket.gethostname() 202 log.debug('worker', 'Setting worker name %s (from hostname)' % 203 options.name) 204 205 if options.feederports is None and not options.randomFeederports: 206 options.feederports = configure.defaultGstPortRange 207 log.debug('worker', 'Using default feederports %r' % 208 options.feederports) 209 210 # check for wrong options/arguments 211 if not options.transport in ['ssl', 'tcp']: 212 sys.stderr.write('ERROR: wrong transport %s, must be ssl or tcp\n' % 213 options.transport) 214 return 1 215 216 # reset FLU_DEBUG which could be different after parsing XML file 217 if options.debug: 218 log.setFluDebug(options.debug) 219 220 if options.daemonizeTo and not options.daemonize: 221 sys.stderr.write( 222 'ERROR: --daemonize-to can only be used with -D/--daemonize.\n') 223 return 1 224 225 if options.serviceName and not options.daemonize: 226 sys.stderr.write( 227 'ERROR: --service-name can only be used with -D/--daemonize.\n') 228 return 1 229 230 brain = worker.WorkerBrain(options) 231 232 # Now bind and listen to our unix and tcp sockets 233 if not brain.listen(): 234 sys.stderr.write('ERROR: Failed to listen on worker ports.\n') 235 return 1 236 237 name = options.name 238 if options.daemonize: 239 if options.serviceName: 240 name = options.serviceName 241 if not options.daemonizeTo: 242 options.daemonizeTo = "/" 243 244 startup("worker", name, options.daemonize, options.daemonizeTo) 245 246 log.debug('worker', 'Running Flumotion version %s' % 247 configure.version) 248 import twisted.copyright 249 log.debug('worker', 'Running against Twisted version %s' % 250 twisted.copyright.version) 251 252 # register all package paths (FIXME: this should go away when 253 # components come from manager) 254 from flumotion.common import setup 255 setup.setupPackagePath() 256 257 # FIXME: why address='localhost' ? 258 authenticator = pb.Authenticator(username=options.username, 259 password=options.password, 260 address='localhost', 261 avatarId=options.name) 262 info = connection.PBConnectionInfo(options.host, options.port, 263 options.transport == "ssl", 264 authenticator) 265 brain.login(info) 266 267 log.info('worker', 268 'Connecting to manager %s using %s' % (info, 269 options.transport.upper())) 270 271 272 # go into the reactor main loop 273 reactor.run() 274 275 return 0
276