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