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