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  import os 
 23  import sys 
 24   
 25  PYGTK_REQ = (2, 6, 3) 
 26   
 27  GST_REQ = {'0.10': {'gstreamer': (0, 10, 0, 1), 
 28                      'gst-python': (0, 10, 0, 1)}} 
 29   
30 -def init_gobject():
31 """ 32 Initialize pygobject. A missing or too-old pygobject will cause a 33 SystemExit exception to be raised. 34 """ 35 try: 36 import pygtk 37 pygtk.require('2.0') 38 39 import gobject 40 except ImportError: 41 raise SystemExit('ERROR: PyGTK could not be found') 42 43 if gobject.pygtk_version < PYGTK_REQ: 44 raise SystemExit('ERROR: PyGTK %s or higher is required' 45 % '.'.join(map(str, PYGTK_REQ))) 46 47 gobject.threads_init()
48
49 -def _init_gst_version(gst_majorminor):
50 51 def tup2version(tup): 52 return '.'.join(map(str, tup))
53 54 if gst_majorminor not in GST_REQ: 55 raise SystemExit('ERROR: Invalid FLU_GST_VERSION: %r (expected ' 56 'one of %r)' % (gst_majorminor, GST_REQ.keys())) 57 58 pygst_req = GST_REQ[gst_majorminor]['gst-python'] 59 gst_req = GST_REQ[gst_majorminor]['gstreamer'] 60 61 try: 62 import pygst 63 pygst.require(gst_majorminor) 64 import gst 65 except ImportError: 66 return False 67 except AssertionError: 68 return False 69 70 try: 71 gst_version = gst.get_gst_version() 72 pygst_version = gst.get_pygst_version() 73 except AttributeError: 74 # get_foo_version() added in 0.10.4, fall back 75 gst_version = gst.gst_version 76 pygst_version = gst.pygst_version 77 78 if gst_req[:2] != gst_version[:2]: 79 raise SystemExit('ERROR: Expected GStreamer %s, but got incompatible %s' 80 % (gst_majorminor, tup2version(gst_version[:2]))) 81 82 if gst_version < gst_req: 83 raise SystemExit('ERROR: GStreamer %s too old; install %s or newer' 84 % (tup2version(gst_version), tup2version(gst_req))) 85 86 if pygst_version < pygst_req: 87 raise SystemExit('ERROR: gst-python %s too old; install %s or newer' 88 % (tup2version(pygst_version), tup2version(pygst_req))) 89 90 return True 91
92 -def init_gst():
93 """ 94 Initialize pygst. A missing or too-old pygst will cause a 95 SystemExit exception to be raised. 96 """ 97 assert 'gobject' in sys.modules, "Run init_gobject() first" 98 99 gst_majorminor = os.getenv('FLU_GST_VERSION') 100 101 if gst_majorminor: 102 if not _init_gst_version(gst_majorminor): 103 raise SystemExit('ERROR: requested GStreamer version %s ' 104 'not available' % gst_majorminor) 105 else: 106 majorminors = GST_REQ.keys() 107 majorminors.sort() 108 while majorminors: 109 majorminor = majorminors.pop() 110 if _init_gst_version(majorminor): 111 gst_majorminor = majorminor 112 break 113 if not gst_majorminor: 114 raise SystemExit('ERROR: no GStreamer available ' 115 '(looking for versions %r)' % (GST_REQ.keys(),)) 116 117 return gst_majorminor
118
119 -def boot(path, gtk=False, gst=True, installReactor=True):
120 if gtk or gst: 121 init_gobject() 122 123 if gst: 124 from flumotion.configure import configure 125 configure.gst_version = init_gst() 126 127 # installing the reactor could override our packager's import hooks ... 128 if installReactor: 129 from twisted.internet import gtk2reactor 130 gtk2reactor.install(useGtk=gtk) 131 # this monkeypatched var exists to let reconnecting factories know 132 # when they should warn about a connection being closed, and when 133 # they shouldn't because the system is shutting down. 134 # 135 # there is no race condition here -- the reactor doesn't handle 136 # signals until it is run(). 137 from twisted.internet import reactor 138 reactor.killed = False 139 def setkilled(killed): 140 reactor.killed = killed
141 reactor.addSystemEventTrigger('before', 'startup', setkilled, False) 142 reactor.addSystemEventTrigger('before', 'shutdown', setkilled, True) 143 144 145 146 # ... so we install them again here to be safe 147 from flumotion.common import package 148 package.getPackager().install() 149 150 from flumotion.twisted import reflect 151 from flumotion.common import errors 152 from flumotion.common import setup 153 154 setup.setup() 155 156 from flumotion.common import log 157 log.logTwisted() 158 159 # we redefine catching 160 __pychecker__ = 'no-reuseattr' 161 162 if os.getenv('FLU_PROFILE'): 163 def catching(proc, *args, **kwargs): 164 import statprof 165 statprof.start() 166 try: 167 return proc(*args, **kwargs) 168 finally: 169 statprof.stop() 170 statprof.display() 171 elif os.getenv('FLU_ATEXIT'): 172 def catching(proc, *args, **kwargs): 173 env = os.getenv('FLU_ATEXIT').split(' ') 174 fqfn = env.pop(0) 175 log.info('atexit', 'FLU_ATEXIT set, will call %s(*%r) on exit', 176 fqfn, env) 177 atexitproc = reflect.namedAny(fqfn) 178 179 try: 180 return proc(*args, **kwargs) 181 finally: 182 log.info('atexit', 'trying to call %r(*%r)', 183 atexitproc, env) 184 atexitproc(*env) 185 else: 186 def catching(proc, *args, **kwargs): 187 return proc(*args, **kwargs) 188 189 main = reflect.namedAny(path) 190 191 try: 192 sys.exit(catching(main, sys.argv)) 193 except errors.SystemError, e: 194 print 'ERROR:', e 195 sys.exit(1) 196