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

Source Code for Module flumotion.common.managerspawner

  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,2008 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  """spawn a local manager and worker""" 
 23   
 24  import gettext 
 25  import os 
 26  import shutil 
 27  import tempfile 
 28   
 29  from twisted.internet import reactor 
 30  from twisted.internet.defer import Deferred 
 31  from twisted.internet.error import ProcessDone 
 32  from twisted.internet.protocol import ProcessProtocol 
 33   
 34  from flumotion.common.signals import SignalMixin 
 35  from flumotion.configure import configure 
 36   
 37  __version__ = "$Rev: 6964 $" 
 38  _ = gettext.gettext 
 39   
 40   
41 -class GreeterProcessProtocol(ProcessProtocol):
42 - def __init__(self):
43 # no parent init 44 self.deferred = Deferred()
45
46 - def processEnded(self, failure):
47 if failure.check(ProcessDone): 48 self.deferred.callback(None) 49 else: 50 self.deferred.callback(failure)
51 52
53 -class LocalManagerSpawner(SignalMixin):
54 """I am a class which can start a local manager and a worker which 55 connects to it. 56 It's mainly used by the greeter in a debug mode and by the testsuite 57 """ 58 __signals__ = ['description-changed', 59 'error', 60 'finished', 61 ] 62
63 - def __init__(self, port):
64 self._path = tempfile.mkdtemp(suffix='.flumotion') 65 self._confDir = os.path.join(self._path, 'etc') 66 self._logDir = os.path.join(self._path, 'var', 'log') 67 self._runDir = os.path.join(self._path, 'var', 'run') 68 self._port = port
69 70 # Public 71
72 - def getPort(self):
73 return self._port
74
75 - def getConfDir(self):
76 return self._confDir
77
78 - def getLogDir(self):
79 return self._logDir
80
81 - def getRunDir(self):
82 return self._runDir
83
84 - def start(self):
85 # We need to run 4 commands in a row, and each of them can fail 86 d = Deferred() 87 88 def chain(args, description, failMessage): 89 d.addCallback(self._spawnProcess, args, description, failMessage)
90 91 for serviceName in [_('manager'), _('worker')]: 92 chain(["flumotion", 93 "-C", self._confDir, 94 "-L", self._logDir, 95 "-R", self._runDir, 96 "create", serviceName, 97 "admin", str(self._port)], 98 _('Creating %s ...') % serviceName, 99 _("Could not create %s." % serviceName)) 100 chain(["flumotion", 101 "-C", self._confDir, 102 "-L", self._logDir, 103 "-R", self._runDir, 104 "start", serviceName, "admin"], 105 _('Starting %s ...' % serviceName), 106 _("Could not start %s." % serviceName)) 107 108 d.addErrback(lambda f: None) 109 110 def done(result): 111 self._finished()
112 d.addCallback(done) 113 114 # start chain 115 d.callback(None) 116 117 return d 118
119 - def stop(self, cleanUp=False):
120 d = Deferred() 121 122 def chain(args, description, failMessage): 123 d.addCallback(self._spawnProcess, args, description, failMessage)
124 125 for serviceName in [_('manager'), _('worker')]: 126 chain(["flumotion", 127 "-C", self._confDir, 128 "-L", self._logDir, 129 "-R", self._runDir, 130 "stop", serviceName, "admin"], '', '') 131 132 def done(result): 133 if cleanUp: 134 self._cleanUp() 135 d.addCallback(done) 136 137 # start chain 138 d.callback(None) 139 return d 140 141 # Private 142
143 - def _finished(self):
144 self.emit('finished')
145
146 - def _error(self, failure, failMessage, args):
147 self.emit('error', failure, failMessage, args)
148
149 - def _setDescription(self, description):
150 self.emit('description-changed', description)
151
152 - def _spawnProcess(self, result, args, description, failMessage):
153 self._setDescription(description) 154 args[0] = os.path.join(configure.sbindir, args[0]) 155 protocol = GreeterProcessProtocol() 156 env = os.environ.copy() 157 paths = env['PATH'].split(os.pathsep) 158 if configure.bindir not in paths: 159 paths.insert(0, configure.bindir) 160 env['PATH'] = os.pathsep.join(paths) 161 reactor.spawnProcess(protocol, args[0], args, env=env) 162 def error(failure, failMessage): 163 self._error(failure, failMessage, args) 164 return failure
165 protocol.deferred.addErrback(error, failMessage) 166 return protocol.deferred 167
168 - def _cleanUp(self):
169 shutil.rmtree(self._path)
170