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: 6988 $"
39 defaultSSLPort = configure.defaultSSLManagerPort
40 defaultTCPPort = configure.defaultTCPManagerPort
41
43 usagemessage = "usage: %prog [options] manager.xml flow1.xml [...]"
44 desc = "The manager is the core component of the Flumotion streaming\
45 server. It takes its configuration from one or more planet configuration\
46 files. The first file is mandatory, and contains base configuration \
47 information for the manager. Zero or more additional configuration files\
48 can be provided, these are used to configure flows that the manager should run\
49 on available workers."
50
51 parser = OptionParser(usage=usagemessage, description=desc,
52 domain="flumotion-manager")
53
54 group = OptionGroup(parser, "manager options")
55 group.add_option('-H', '--hostname',
56 action="store", type="string", dest="host",
57 help="hostname to listen as")
58 group.add_option('-P', '--port',
59 action="store", type="int", dest="port",
60 default=None,
61 help="port to listen on [default %d (ssl) or %d (tcp)]" % (defaultSSLPort, defaultTCPPort))
62 group.add_option('-T', '--transport',
63 action="store", type="string", dest="transport",
64 help="transport protocol to use (tcp/ssl) [default ssl]")
65 group.add_option('-C', '--certificate',
66 action="store", type="string", dest="certificate",
67 default=None,
68 help="PEM certificate file (for SSL) "
69 "[default default.pem]")
70 group.add_option('-n', '--name',
71 action="store", type="string", dest="name",
72 help="manager name")
73 group.add_option('-s', '--service-name',
74 action="store", type="string", dest="serviceName",
75 help="name to use for log and pid files "
76 "when run as a daemon")
77 group.add_option('-D', '--daemonize',
78 action="store_true", dest="daemonize",
79 default=False,
80 help="run in background as a daemon")
81 group.add_option('', '--daemonize-to',
82 action="store", dest="daemonizeTo",
83 help="what directory to run from when daemonizing")
84
85 parser.add_option('-L', '--logdir',
86 action="store", dest="logdir",
87 help="flumotion log directory (default: %s)" %
88 configure.logdir)
89 parser.add_option('-R', '--rundir',
90 action="store", dest="rundir",
91 help="flumotion run directory (default: %s)" %
92 configure.rundir)
93
94 parser.add_option_group(group)
95
96 return parser
97
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 os.environ.has_key('FLU_DEBUG'):
162 options.debug = cfg.manager.fludebug
163 log.debug('manager', 'Setting debug level to config file value %s' %
164 options.debug)
165
166
167 if options.debug:
168 log.setFluDebug(options.debug)
169
170
171 if not options.host:
172 options.host = ""
173 if not options.transport:
174 options.transport = 'ssl'
175 if not options.port:
176 if options.transport == "tcp":
177 options.port = defaultTCPPort
178 elif options.transport == "ssl":
179 options.port = defaultSSLPort
180 if not options.certificate and options.transport == 'ssl':
181 options.certificate = 'default.pem'
182 if not options.name:
183
184
185 head, filename = os.path.split(os.path.abspath(planetFile))
186 head, name = os.path.split(head)
187 head, managers = os.path.split(head)
188 if managers != 'managers':
189 options.name = 'unnamed'
190 log.debug('manager', 'Setting name to unnamed')
191 else:
192 options.name = name
193 log.debug('manager', 'Setting name to %s based on path' % name)
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=managerConfigDir)
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.FatalError, 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 startup("manager", name, options.daemonize, options.daemonizeTo)
258
259 reactor.run()
260
261 return 0
262