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