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