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 os
27 import sys
28
29 from twisted.internet import reactor, error
30
31 from flumotion.manager import manager, config
32 from flumotion.common import log, errors, setup
33 from flumotion.common import server
34 from flumotion.common.options import OptionGroup, OptionParser
35 from flumotion.common.process import startup
36 from flumotion.configure import configure
37
38 __version__ = "$Rev: 7162 $"
39 defaultSSLPort = configure.defaultSSLManagerPort
40 defaultTCPPort = configure.defaultTCPManagerPort
41
42
44 usagemessage = "usage: %prog [options] manager.xml flow1.xml [...]"
45 desc = "The manager is the core component of the Flumotion streaming\
46 server. It takes its configuration from one or more planet configuration\
47 files. The first file is mandatory, and contains base configuration \
48 information for the manager. Zero or more additional configuration files\
49 can be provided, these are used to configure flows that the manager should\
50 run on available workers."
51
52 parser = OptionParser(usage=usagemessage, description=desc,
53 domain="flumotion-manager")
54
55 group = OptionGroup(parser, "manager options")
56 group.add_option('-H', '--hostname',
57 action="store", type="string", dest="host",
58 help="hostname to listen as")
59 group.add_option('-P', '--port',
60 action="store", type="int", dest="port",
61 default=None,
62 help="port to listen on [default %d (ssl) or %d (tcp)]" %
63 (defaultSSLPort, defaultTCPPort))
64 group.add_option('-T', '--transport',
65 action="store", type="string", dest="transport",
66 help="transport protocol to use (tcp/ssl) [default ssl]")
67 group.add_option('-C', '--certificate',
68 action="store", type="string", dest="certificate",
69 default=None,
70 help="PEM certificate file (for SSL) "
71 "[default default.pem]")
72 group.add_option('-n', '--name',
73 action="store", type="string", dest="name",
74 help="manager name")
75 group.add_option('-s', '--service-name',
76 action="store", type="string", dest="serviceName",
77 help="name to use for log and pid files "
78 "when run as a daemon")
79 group.add_option('-D', '--daemonize',
80 action="store_true", dest="daemonize",
81 default=False,
82 help="run in background as a daemon")
83 group.add_option('', '--daemonize-to',
84 action="store", dest="daemonizeTo",
85 help="what directory to run from when daemonizing")
86
87 parser.add_option('-L', '--logdir',
88 action="store", dest="logdir",
89 help="flumotion log directory (default: %s)" %
90 configure.logdir)
91 parser.add_option('-R', '--rundir',
92 action="store", dest="rundir",
93 help="flumotion run directory (default: %s)" %
94 configure.rundir)
95
96 parser.add_option_group(group)
97
98 return parser
99
100
107
108
110 parser = _createParser()
111
112 log.debug('manager', 'Parsing arguments (%r)' % ', '.join(args))
113 options, args = parser.parse_args(args)
114
115
116 for d in ['logdir', 'rundir']:
117 o = getattr(options, d, None)
118 if o:
119 log.debug('manager', 'Setting configure.%s to %s' % (d, o))
120 setattr(configure, d, o)
121
122
123 if len(args) <= 1:
124 log.warning('manager', 'Please specify a planet configuration file')
125 sys.stderr.write("Please specify a planet configuration file.\n")
126 return 1
127
128 planetFile = args[1]
129 try:
130 cfg = config.ManagerConfigParser(planetFile)
131 except IOError, e:
132 sys.stderr.write("ERROR: Could not read configuration from '%s':\n" %
133 planetFile)
134 sys.stderr.write("ERROR: %s\n" % e.strerror)
135 return 1
136 except errors.ConfigError, e:
137 sys.stderr.write("ERROR: Could not read configuration from '%s':\n" %
138 planetFile)
139 sys.stderr.write("ERROR: %s\n" % e.args[0])
140 return 1
141
142 managerConfigDir = os.path.abspath(os.path.dirname(planetFile))
143
144
145 if cfg.manager:
146 if not options.host and cfg.manager.host:
147 options.host = cfg.manager.host
148 log.debug('manager', 'Setting manager host to %s' % options.host)
149 if not options.port and cfg.manager.port:
150 options.port = cfg.manager.port
151 log.debug('manager', 'Setting manager port to %s' % options.port)
152 if not options.transport and cfg.manager.transport:
153 options.transport = cfg.manager.transport
154 log.debug('manager', 'Setting manager transport to %s' %
155 options.transport)
156 if not options.certificate and cfg.manager.certificate:
157 options.certificate = cfg.manager.certificate
158 log.debug('manager', 'Using certificate %s' %
159 options.certificate)
160 if not options.name and cfg.manager.name:
161 options.name = cfg.manager.name
162 log.debug('manager', 'Setting manager name to %s' % options.name)
163
164 if not options.debug and cfg.manager.fludebug \
165 and not 'FLU_DEBUG' in os.environ:
166 options.debug = cfg.manager.fludebug
167 log.debug('manager',
168 'Setting debug level to config file value %s' %
169 options.debug)
170
171
172 if options.debug:
173 log.setFluDebug(options.debug)
174
175
176 if not options.host:
177 options.host = ""
178 if not options.transport:
179 options.transport = 'ssl'
180 if not options.port:
181 if options.transport == "tcp":
182 options.port = defaultTCPPort
183 elif options.transport == "ssl":
184 options.port = defaultSSLPort
185 if not options.certificate and options.transport == 'ssl':
186 options.certificate = 'default.pem'
187 if not options.name:
188
189
190 head, filename = os.path.split(os.path.abspath(planetFile))
191 head, name = os.path.split(head)
192 head, managers = os.path.split(head)
193 if managers != 'managers':
194 options.name = 'unnamed'
195 log.debug('manager', 'Setting name to unnamed')
196 else:
197 options.name = name
198 log.debug('manager', 'Setting name to %s based on path' % name)
199
200
201 if not options.transport in ['ssl', 'tcp']:
202 sys.stderr.write('ERROR: wrong transport %s, must be ssl or tcp\n' %
203 options.transport)
204 return 1
205
206
207 setup.setupPackagePath()
208
209
210 log.info('manager', "Starting manager '%s'" % options.name)
211
212 log.debug('manager', 'Running Flumotion version %s' %
213 configure.version)
214 import twisted.copyright
215 log.debug('manager', 'Running against Twisted version %s' %
216 twisted.copyright.version)
217 from flumotion.project import project
218 for p in project.list():
219 log.debug('manager', 'Registered project %s version %s' % (
220 p, project.get(p, 'version')))
221
222 vishnu = manager.Vishnu(options.name, configDir=managerConfigDir)
223 for managerConfigFile in args[1:]:
224 vishnu.loadManagerConfigurationXML(managerConfigFile)
225
226 paths = [os.path.abspath(filename) for filename in args[1:]]
227 reactor.callLater(0, _initialLoadConfig, vishnu, paths)
228 reactor.callLater(0, vishnu.startManagerPlugs)
229
230
231 myServer = server.Server(vishnu)
232 try:
233 if options.transport == "ssl":
234 myServer.startSSL(options.host, options.port, options.certificate,
235 configure.configdir)
236 elif options.transport == "tcp":
237 myServer.startTCP(options.host, options.port)
238 except error.CannotListenError, e:
239
240 message = "Could not listen on port %d: %s" % (
241 e.port, e.socketError.args[1])
242 raise errors.FatalError, message
243
244 if options.daemonizeTo and not options.daemonize:
245 sys.stderr.write(
246 'ERROR: --daemonize-to can only be used with -D/--daemonize.\n')
247 return 1
248
249 if options.serviceName and not options.daemonize:
250 sys.stderr.write(
251 'ERROR: --service-name can only be used with -D/--daemonize.\n')
252 return 1
253
254 name = options.name
255
256 if options.daemonize:
257 if options.serviceName:
258 name = options.serviceName
259 if not options.daemonizeTo:
260 options.daemonizeTo = "/"
261
262 startup("manager", name, options.daemonize, options.daemonizeTo)
263
264 reactor.run()
265
266 return 0
267