1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 manager main function
24 """
25
26 import optparse
27 import os
28 import sys
29 import traceback
30
31 from twisted.internet import reactor, error
32
33 from flumotion.manager import manager
34 from flumotion.common import log, config, common, errors, setup
35 from flumotion.configure import configure
36 from flumotion.common import server
37
38 defaultSSLPort = configure.defaultSSLManagerPort
39 defaultTCPPort = configure.defaultTCPManagerPort
40
42 usagemessage = "usage: %prog [options] manager.xml flow1.xml [...]"
43 desc = "The manager is the core component of the Flumotion streaming\
44 server. It takes its configuration from one or more planet configuration\
45 files. The first file is mandatory, and contains base configuration \
46 information for the manager. Zero or more additional configuration files\
47 can be provided, these are used to configure flows that the manager should run\
48 on available workers."
49
50 parser = optparse.OptionParser(usage=usagemessage, description=desc)
51 parser.add_option('-d', '--debug',
52 action="store", type="string", dest="debug",
53 help="set debug levels")
54 parser.add_option('-v', '--verbose',
55 action="store_true", dest="verbose",
56 help="be verbose")
57 parser.add_option('', '--version',
58 action="store_true", dest="version",
59 default=False,
60 help="show version information")
61
62 group = optparse.OptionGroup(parser, "manager options")
63 group.add_option('-H', '--hostname',
64 action="store", type="string", dest="host",
65 help="hostname to listen as")
66 group.add_option('-P', '--port',
67 action="store", type="int", dest="port",
68 default=None,
69 help="port to listen on [default %d (ssl) or %d (tcp)]" % (defaultSSLPort, defaultTCPPort))
70 group.add_option('-T', '--transport',
71 action="store", type="string", dest="transport",
72 help="transport protocol to use (tcp/ssl) [default ssl]")
73 group.add_option('-C', '--certificate',
74 action="store", type="string", dest="certificate",
75 default=None,
76 help="PEM certificate file (for SSL) "
77 "[default default.pem]")
78 group.add_option('-n', '--name',
79 action="store", type="string", dest="name",
80 help="manager name")
81 group.add_option('-s', '--service-name',
82 action="store", type="string", dest="serviceName",
83 help="name to use for log and pid files "
84 "when run as a daemon")
85 group.add_option('-D', '--daemonize',
86 action="store_true", dest="daemonize",
87 default=False,
88 help="run in background as a daemon")
89 group.add_option('', '--daemonize-to',
90 action="store", dest="daemonizeTo",
91 help="what directory to run from when daemonizing")
92
93 parser.add_option('-L', '--logdir',
94 action="store", dest="logdir",
95 help="flumotion log directory (default: %s)" %
96 configure.logdir)
97 parser.add_option('-R', '--rundir',
98 action="store", dest="rundir",
99 help="flumotion run directory (default: %s)" %
100 configure.rundir)
101
102 parser.add_option_group(group)
103
104 return parser
105
117
140
142
143 args = [arg for arg in args if not arg.startswith('--gst')]
144
145 parser = _createParser()
146
147 log.debug('manager', 'Parsing arguments (%r)' % ', '.join(args))
148 options, args = parser.parse_args(args)
149
150
151 for d in ['logdir', 'rundir']:
152 o = getattr(options, d, None)
153 if o:
154 log.debug('manager', 'Setting configure.%s to %s' % (d, o))
155 setattr(configure, d, o)
156
157
158 if options.verbose:
159 options.debug = "*:3"
160
161
162 if options.version:
163 print common.version("flumotion-manager")
164 return 0
165
166
167 if len(args) <= 1:
168 log.warning('manager', 'Please specify a planet configuration file')
169 sys.stderr.write("Please specify a planet configuration file.\n")
170 return 1
171
172 planetFile = args[1]
173 try:
174 cfg = config.FlumotionConfigXML(planetFile)
175 except IOError, e:
176 sys.stderr.write("ERROR: Could not read configuration from '%s':\n" %
177 planetFile)
178 sys.stderr.write("ERROR: %s\n" % e.strerror)
179 return 1
180 except errors.ConfigError, e:
181 sys.stderr.write("ERROR: Could not read configuration from '%s':\n" %
182 planetFile)
183 sys.stderr.write("ERROR: %s\n" % e.args[0])
184 return 1
185
186 configDir = os.path.abspath(os.path.dirname(planetFile))
187
188
189 if cfg.manager:
190 if not options.host and cfg.manager.host:
191 options.host = cfg.manager.host
192 log.debug('manager', 'Setting manager host to %s' % options.host)
193 if not options.port and cfg.manager.port:
194 options.port = cfg.manager.port
195 log.debug('manager', 'Setting manager port to %s' % options.port)
196 if not options.transport and cfg.manager.transport:
197 options.transport = cfg.manager.transport
198 log.debug('manager', 'Setting manager transport to %s' %
199 options.transport)
200 if not options.certificate and cfg.manager.certificate:
201 options.certificate = cfg.manager.certificate
202 log.debug('manager', 'Using certificate %s' %
203 options.certificate)
204 if not options.name and cfg.manager.name:
205 options.name = cfg.manager.name
206 log.debug('manager', 'Setting manager name to %s' % options.name)
207
208 if not options.debug and cfg.manager.fludebug \
209 and not os.environ.has_key('FLU_DEBUG'):
210 options.debug = cfg.manager.fludebug
211 log.debug('manager', 'Setting debug level to config file value %s' %
212 options.debug)
213
214
215 if options.debug:
216 log.setFluDebug(options.debug)
217
218
219 if not options.host:
220 options.host = ""
221 if not options.transport:
222 options.transport = 'ssl'
223 if not options.port:
224 if options.transport == "tcp":
225 options.port = defaultTCPPort
226 elif options.transport == "ssl":
227 options.port = defaultSSLPort
228 if not options.certificate and options.transport == 'ssl':
229 options.certificate = 'default.pem'
230 if not options.name:
231 try:
232
233
234 head, filename = os.path.split(os.path.abspath(planetFile))
235 head, name = os.path.split(head)
236 head, managers = os.path.split(head)
237 if managers != 'managers':
238 raise
239 options.name = name
240 log.debug('manager', 'Setting name to %s based on path' % name)
241 except:
242 options.name = 'unnamed'
243 log.debug('manager', 'Setting name to unnamed')
244
245
246 if not options.transport in ['ssl', 'tcp']:
247 sys.stderr.write('ERROR: wrong transport %s, must be ssl or tcp\n' %
248 options.transport)
249 return 1
250
251
252 setup.setupPackagePath()
253
254
255 log.info('manager', "Starting manager '%s'" % options.name)
256
257 log.debug('manager', 'Running Flumotion version %s' %
258 configure.version)
259 import twisted.copyright
260 log.debug('manager', 'Running against Twisted version %s' %
261 twisted.copyright.version)
262 from flumotion.project import project
263 for p in project.list():
264 log.debug('manager', 'Registered project %s version %s' % (
265 p, project.get(p, 'version')))
266
267 vishnu = manager.Vishnu(options.name, configDir=configDir)
268
269 paths = [os.path.abspath(filename) for filename in args[1:]]
270 reactor.callLater(0, _initialLoadConfig, vishnu, paths)
271
272
273 myServer = server.Server(vishnu)
274 try:
275 if options.transport == "ssl":
276 myServer.startSSL(options.host, options.port, options.certificate,
277 configure.configdir)
278 elif options.transport == "tcp":
279 myServer.startTCP(options.host, options.port)
280 except error.CannotListenError, e:
281
282 message = "Could not listen on port %d: %s" % (
283 e.port, e.socketError.args[1])
284 raise errors.SystemError, message
285
286 if options.daemonizeTo and not options.daemonize:
287 sys.stderr.write(
288 'ERROR: --daemonize-to can only be used with -D/--daemonize.\n')
289 return 1
290
291 if options.serviceName and not options.daemonize:
292 sys.stderr.write(
293 'ERROR: --service-name can only be used with -D/--daemonize.\n')
294 return 1
295
296 name = options.name
297
298 if options.daemonize:
299 if options.serviceName:
300 name = options.serviceName
301
302 common.startup("manager", name, options.daemonize,
303 options.daemonizeTo)
304
305 reactor.run()
306
307 return 0
308