Package flumotion :: Package common :: Module boot
[hide private]

Source Code for Module flumotion.common.boot

  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  """boostrapping functions for flumotion""" 
 23   
 24  import os 
 25  import sys 
 26   
 27  from flumotion.common.log import safeprintf 
 28   
 29  __version__ = "$Rev: 6988 $" 
 30  # Keep in sync with configure.ac 
 31  PYGTK_REQ = (2, 8, 4) 
 32  KIWI_REQ = (1, 9, 13) 
 33   
 34  GST_REQ = {'0.10': {'gstreamer': (0, 10, 0, 1), 
 35                      'gst-python': (0, 10, 0, 1)}} 
 36   
37 -def init_gobject():
38 """ 39 Initialize pygobject. A missing or too-old pygobject will cause a 40 SystemExit exception to be raised. 41 """ 42 try: 43 import pygtk 44 pygtk.require('2.0') 45 46 import gobject 47 except ImportError: 48 raise SystemExit('ERROR: PyGTK could not be found') 49 50 if gobject.pygtk_version < PYGTK_REQ: 51 raise SystemExit('ERROR: PyGTK %s or higher is required' 52 % '.'.join(map(str, PYGTK_REQ))) 53 54 gobject.threads_init()
55
56 -def _init_gst_version(gst_majorminor):
57 58 def tup2version(tup): 59 return '.'.join(map(str, tup))
60 61 if gst_majorminor not in GST_REQ: 62 raise SystemExit('ERROR: Invalid FLU_GST_VERSION: %r (expected ' 63 'one of %r)' % (gst_majorminor, GST_REQ.keys())) 64 65 pygst_req = GST_REQ[gst_majorminor]['gst-python'] 66 gst_req = GST_REQ[gst_majorminor]['gstreamer'] 67 68 try: 69 import pygst 70 pygst.require(gst_majorminor) 71 import gst 72 except ImportError: 73 return False 74 except AssertionError: 75 return False 76 77 try: 78 gst_version = gst.get_gst_version() 79 pygst_version = gst.get_pygst_version() 80 except AttributeError: 81 # get_foo_version() added in 0.10.4, fall back 82 gst_version = gst.gst_version 83 pygst_version = gst.pygst_version 84 85 if gst_req[:2] != gst_version[:2]: 86 raise SystemExit('ERROR: Expected GStreamer %s, but got incompatible %s' 87 % (gst_majorminor, tup2version(gst_version[:2]))) 88 89 if gst_version < gst_req: 90 raise SystemExit('ERROR: GStreamer %s too old; install %s or newer' 91 % (tup2version(gst_version), tup2version(gst_req))) 92 93 if pygst_version < pygst_req: 94 raise SystemExit('ERROR: gst-python %s too old; install %s or newer' 95 % (tup2version(pygst_version), tup2version(pygst_req))) 96 97 return True 98
99 -def init_gst():
100 """ 101 Initialize pygst. A missing or too-old pygst will cause a 102 SystemExit exception to be raised. 103 """ 104 assert 'gobject' in sys.modules, "Run init_gobject() first" 105 106 gst_majorminor = os.getenv('FLU_GST_VERSION') 107 108 if gst_majorminor: 109 if not _init_gst_version(gst_majorminor): 110 raise SystemExit('ERROR: requested GStreamer version %s ' 111 'not available' % gst_majorminor) 112 else: 113 majorminors = GST_REQ.keys() 114 majorminors.sort() 115 while majorminors: 116 majorminor = majorminors.pop() 117 if _init_gst_version(majorminor): 118 gst_majorminor = majorminor 119 break 120 if not gst_majorminor: 121 raise SystemExit('ERROR: no GStreamer available ' 122 '(looking for versions %r)' % (GST_REQ.keys(),)) 123 124 return gst_majorminor
125
126 -def init_kiwi():
127 try: 128 from kiwi.__version__ import version as kiwi_version 129 except ImportError: 130 return False 131 132 if kiwi_version < KIWI_REQ: 133 raise SystemExit('ERROR: Kiwi %s or higher is required' 134 % '.'.join(map(str, KIWI_REQ))) 135 136 return True
137 138 USE_GOPTION_PARSER = False
139 -def init_option_parser(gtk, gst):
140 # We should only use the GOption parser if we are already going to 141 # import gobject, and if we can find a recent enough version of 142 # pygobject on our system. There were bugs in the GOption parsing 143 # until pygobject 2.15.0, so just revert to optparse if our 144 # pygobject is too old. 145 global USE_GOPTION_PARSER 146 if not gtk and not gst: 147 USE_GOPTION_PARSER = False 148 else: 149 import gobject 150 if getattr(gobject, 'pygobject_version', ()) >= (2, 15, 0): 151 USE_GOPTION_PARSER = True 152 else: 153 USE_GOPTION_PARSER = False
154 155 USE_GTK = False 156 USE_GST = True
157 -def boot(path, gtk=False, gst=True, installReactor=True):
158 # python 2.5 and twisted < 2.5 don't work together 159 pythonMM = sys.version_info[0:2] 160 from twisted.copyright import version 161 twistedMM = tuple([int(n) for n in version.split('.')[0:2]]) 162 if pythonMM >= (2, 5) and twistedMM < (2, 5): 163 raise SystemError( 164 "Twisted versions older than 2.5.0 do not work with " 165 "Python 2.5 and newer. " 166 "Please upgrade Twisted or downgrade Python.") 167 168 if gtk or gst: 169 init_gobject() 170 171 if gst: 172 from flumotion.configure import configure 173 configure.gst_version = init_gst() 174 175 global USE_GTK, USE_GST 176 USE_GTK=gtk 177 USE_GST=gst 178 init_option_parser(gtk, gst) 179 180 # installing the reactor could override our packager's import hooks ... 181 if installReactor: 182 from twisted.internet import gtk2reactor 183 gtk2reactor.install(useGtk=gtk) 184 from twisted.internet import reactor 185 186 # ... so we install them again here to be safe 187 from flumotion.common import package 188 package.getPackager().install() 189 190 # this monkeypatched var exists to let reconnecting factories know 191 # when they should warn about a connection being closed, and when 192 # they shouldn't because the system is shutting down. 193 # 194 # there is no race condition here -- the reactor doesn't handle 195 # signals until it is run(). 196 reactor.killed = False 197 def setkilled(killed): 198 reactor.killed = killed
199 reactor.addSystemEventTrigger('before', 'startup', setkilled, False) 200 reactor.addSystemEventTrigger('before', 'shutdown', setkilled, True) 201 202 from flumotion.twisted import reflect 203 from flumotion.common import errors 204 from flumotion.common import setup 205 206 setup.setup() 207 208 from flumotion.common import log 209 log.logTwisted() 210 211 # we redefine catching 212 __pychecker__ = 'no-reuseattr' 213 214 if os.getenv('FLU_PROFILE'): 215 def catching(proc, *args, **kwargs): 216 import statprof 217 statprof.start() 218 try: 219 return proc(*args, **kwargs) 220 finally: 221 statprof.stop() 222 statprof.display() 223 elif os.getenv('FLU_ATEXIT'): 224 def catching(proc, *args, **kwargs): 225 env = os.getenv('FLU_ATEXIT').split(' ') 226 fqfn = env.pop(0) 227 log.info('atexit', 'FLU_ATEXIT set, will call %s(*%r) on exit', 228 fqfn, env) 229 atexitproc = reflect.namedAny(fqfn) 230 231 try: 232 return proc(*args, **kwargs) 233 finally: 234 log.info('atexit', 'trying to call %r(*%r)', 235 atexitproc, env) 236 atexitproc(*env) 237 else: 238 def catching(proc, *args, **kwargs): 239 return proc(*args, **kwargs) 240 241 main = reflect.namedAny(path) 242 243 try: 244 sys.exit(catching(main, sys.argv)) 245 except (errors.FatalError, SystemError), e: 246 safeprintf(sys.stderr, 'ERROR: %s\n', e) 247 sys.exit(1) 248