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

Source Code for Module flumotion.manager.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  """ 
 23  manager main function 
 24  """ 
 25   
 26  import os 
 27  import sys 
 28   
 29  from twisted.internet import reactor, error 
 30   
 31  from flumotion.manager import manager, config 
 32  from flumotion.common import log, errors, setup 
 33  from flumotion.common import server 
 34  from flumotion.common.options import OptionGroup, OptionParser 
 35  from flumotion.common.process import startup 
 36  from flumotion.configure import configure 
 37   
 38  __version__ = "$Rev$" 
 39  defaultSSLPort = configure.defaultSSLManagerPort 
 40  defaultTCPPort = configure.defaultTCPManagerPort 
 41   
 42   
43 -def _createParser():
44 usagemessage = "usage: %prog [options] manager.xml flow1.xml [...]" 45 desc = "The manager is the core component of the Flumotion streaming\ 46 server. It takes its configuration from one or more planet configuration\ 47 files. The first file is mandatory, and contains base configuration \ 48 information for the manager. Zero or more additional configuration files\ 49 can be provided, these are used to configure flows that the manager should\ 50 run on available workers." 51 52 parser = OptionParser(usage=usagemessage, description=desc, 53 domain="flumotion-manager") 54 55 group = OptionGroup(parser, "manager options") 56 group.add_option('-H', '--hostname', 57 action="store", type="string", dest="host", 58 help="hostname to listen as") 59 group.add_option('-P', '--port', 60 action="store", type="int", dest="port", 61 default=None, 62 help="port to listen on [default %d (ssl) or %d (tcp)]" % 63 (defaultSSLPort, defaultTCPPort)) 64 group.add_option('-T', '--transport', 65 action="store", type="string", dest="transport", 66 help="transport protocol to use (tcp/ssl) [default ssl]") 67 group.add_option('-C', '--certificate', 68 action="store", type="string", dest="certificate", 69 default=None, 70 help="PEM certificate file (for SSL) " 71 "[default default.pem]") 72 group.add_option('-n', '--name', 73 action="store", type="string", dest="name", 74 help="manager name") 75 group.add_option('-s', '--service-name', 76 action="store", type="string", dest="serviceName", 77 help="name to use for log and pid files " 78 "when run as a daemon") 79 group.add_option('-D', '--daemonize', 80 action="store_true", dest="daemonize", 81 default=False, 82 help="run in background as a daemon") 83 group.add_option('', '--daemonize-to', 84 action="store", dest="daemonizeTo", 85 help="what directory to run from when daemonizing") 86 87 parser.add_option('-L', '--logdir', 88 action="store", dest="logdir", 89 help="flumotion log directory (default: %s)" % 90 configure.logdir) 91 parser.add_option('-R', '--rundir', 92 action="store", dest="rundir", 93 help="flumotion run directory (default: %s)" % 94 configure.rundir) 95 96 parser.add_option_group(group) 97 98 return parser
99 100
101 -def _initialLoadConfig(vishnu, paths):
102 # this is used with a callLater for the initial config loading 103 # since this is run after daemonizing, it should show errors, but not stop 104 for path in paths: 105 log.debug('manager', 'Loading configuration file from (%s)' % path) 106 vishnu.loadComponentConfigurationXML(path, manager.LOCAL_IDENTITY)
107 108
109 -def main(args):
110 parser = _createParser() 111 112 log.debug('manager', 'Parsing arguments (%r)' % ', '.join(args)) 113 options, args = parser.parse_args(args) 114 115 # Force options down configure's throat 116 for d in ['logdir', 'rundir']: 117 o = getattr(options, d, None) 118 if o: 119 log.debug('manager', 'Setting configure.%s to %s' % (d, o)) 120 setattr(configure, d, o) 121 122 # parse planet config file 123 if len(args) <= 1: 124 log.warning('manager', 'Please specify a planet configuration file') 125 sys.stderr.write("Please specify a planet configuration file.\n") 126 return 1 127 128 planetFile = args[1] 129 try: 130 cfg = config.ManagerConfigParser(planetFile) 131 except IOError, e: 132 sys.stderr.write("ERROR: Could not read configuration from '%s':\n" % 133 planetFile) 134 sys.stderr.write("ERROR: %s\n" % e.strerror) 135 return 1 136 except errors.ConfigError, e: 137 sys.stderr.write("ERROR: Could not read configuration from '%s':\n" % 138 planetFile) 139 sys.stderr.write("ERROR: %s\n" % e.args[0]) 140 return 1 141 142 managerConfigDir = os.path.abspath(os.path.dirname(planetFile)) 143 144 # now copy over stuff from config that is not set yet 145 if cfg.manager: 146 if not options.host and cfg.manager.host: 147 options.host = cfg.manager.host 148 log.debug('manager', 'Setting manager host to %s' % options.host) 149 if not options.port and cfg.manager.port: 150 options.port = cfg.manager.port 151 log.debug('manager', 'Setting manager port to %s' % options.port) 152 if not options.transport and cfg.manager.transport: 153 options.transport = cfg.manager.transport 154 log.debug('manager', 'Setting manager transport to %s' % 155 options.transport) 156 if not options.certificate and cfg.manager.certificate: 157 options.certificate = cfg.manager.certificate 158 log.debug('manager', 'Using certificate %s' % 159 options.certificate) 160 if not options.name and cfg.manager.name: 161 options.name = cfg.manager.name 162 log.debug('manager', 'Setting manager name to %s' % options.name) 163 # environment debug > command-line debug > config file debug 164 if not options.debug and cfg.manager.fludebug \ 165 and not 'FLU_DEBUG' in os.environ: 166 options.debug = cfg.manager.fludebug 167 log.debug('manager', 168 'Setting debug level to config file value %s' % 169 options.debug) 170 171 # set debug level as soon as we can after deciding 172 if options.debug: 173 log.setFluDebug(options.debug) 174 175 # set default values for all unset options 176 if not options.host: 177 options.host = "" # needed for bind to work 178 if not options.transport: 179 options.transport = 'ssl' 180 if not options.port: 181 if options.transport == "tcp": 182 options.port = defaultTCPPort 183 elif options.transport == "ssl": 184 options.port = defaultSSLPort 185 if not options.certificate and options.transport == 'ssl': 186 options.certificate = 'default.pem' 187 if not options.name: 188 # if the file is in a directory under a 'managers' directory, 189 # use the parent directory name 190 head, filename = os.path.split(os.path.abspath(planetFile)) 191 head, name = os.path.split(head) 192 head, managers = os.path.split(head) 193 if managers != 'managers': 194 options.name = 'unnamed' 195 log.debug('manager', 'Setting name to unnamed') 196 else: 197 options.name = name 198 log.debug('manager', 'Setting name to %s based on path' % name) 199 200 # check for wrong options/arguments 201 if not options.transport in ['ssl', 'tcp']: 202 sys.stderr.write('ERROR: wrong transport %s, must be ssl or tcp\n' % 203 options.transport) 204 return 1 205 206 # register package path 207 setup.setupPackagePath() 208 209 # log our standardized starting marker 210 log.info('manager', "Starting manager '%s'" % options.name) 211 212 log.debug('manager', 'Running Flumotion version %s' % 213 configure.version) 214 import twisted.copyright 215 log.debug('manager', 'Running against Twisted version %s' % 216 twisted.copyright.version) 217 from flumotion.project import project 218 for p in project.list(): 219 log.debug('manager', 'Registered project %s version %s' % ( 220 p, project.get(p, 'version'))) 221 222 vishnu = manager.Vishnu(options.name, configDir=managerConfigDir) 223 for managerConfigFile in args[1:]: 224 vishnu.loadManagerConfigurationXML(managerConfigFile) 225 226 paths = [os.path.abspath(filename) for filename in args[1:]] 227 reactor.callLater(0, _initialLoadConfig, vishnu, paths) 228 reactor.callLater(0, vishnu.startManagerPlugs) 229 230 # set up server based on transport 231 myServer = server.Server(vishnu) 232 try: 233 if options.transport == "ssl": 234 myServer.startSSL(options.host, options.port, options.certificate, 235 configure.configdir) 236 elif options.transport == "tcp": 237 myServer.startTCP(options.host, options.port) 238 except error.CannotListenError, e: 239 # e is a socket.error() 240 message = "Could not listen on port %d: %s" % ( 241 e.port, e.socketError.args[1]) 242 raise errors.FatalError, message 243 244 if options.daemonizeTo and not options.daemonize: 245 sys.stderr.write( 246 'ERROR: --daemonize-to can only be used with -D/--daemonize.\n') 247 return 1 248 249 if options.serviceName and not options.daemonize: 250 sys.stderr.write( 251 'ERROR: --service-name can only be used with -D/--daemonize.\n') 252 return 1 253 254 name = options.name 255 256 if options.daemonize: 257 if options.serviceName: 258 name = options.serviceName 259 if not options.daemonizeTo: 260 options.daemonizeTo = "/" 261 262 startup("manager", name, options.daemonize, options.daemonizeTo) 263 264 reactor.run() 265 266 return 0
267