1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import os
23 import errno
24
25 import gobject
26 import gtk
27
28 from gettext import gettext as _
29
30 from twisted.internet import reactor, protocol, defer, error
31
32 from flumotion.common.pygobject import gsignal
33 from flumotion.common import log
34 from flumotion.configure import configure
35 from flumotion.admin.gtk import wizard, connections, dialogs
36
37
38
39
40
41
42
43
44
45
46
47
48
50 name = 'initial'
51 title = _('Connect to Flumotion manager')
52 text = _('Flumotion Admin needs to connect to a Flumotion manager.\n') + \
53 _('Choose an option from the list and click "Forward" to begin.')
54 connect_to_existing = None
55 next_pages = ['load_connection', 'connect_to_existing', 'start_new']
56
58 radio_buttons = self.connect_to_existing.get_group()
59
60 for i in range(len(radio_buttons)):
61 if radio_buttons[i].get_active():
62 return radio_buttons[i].get_name()
63 raise AssertionError
64
65 - def setup(self, state, available_pages):
66
67 radio_buttons = self.load_connection.get_group()
68 for w in radio_buttons:
69 w.set_sensitive(w.get_name() in available_pages)
70 if w.get_active() and not w.get_property('sensitive'):
71 getattr(self, available_pages[0]).set_active(True)
72
73
75 name = 'connect_to_existing'
76 title = _('Host information')
77 text = _('Please enter the address where the manager is running.')
78 next_pages = ['authenticate']
79 open_connection = None
80
81 - def setup(self, state, available_pages):
88
91
96
97
123
124
126 name = 'load_connection'
127 title = _('Recent connections')
128 text = _('Please choose a connection from the box below.')
129 connections = None
130 next_pages = []
131
134
137
140
142 info = self.connections.get_selected()
143 for k, v in (('host', info.host), ('port', info.port),
144 ('use_insecure', not info.use_ssl),
145 ('user', info.authenticator.username),
146 ('passwd', info.authenticator.password)):
147 state[k] = v
148 return '*finished*'
149
150 - def setup(self, state, available_pages):
152
155
156 self.deferred = defer.Deferred()
157
163
165 name = 'start_new'
166 title = _('Start a new manager and worker')
167 text = _("""This will start a new manager and worker for you.
168
169 The manager and worker will run under your user account.
170 The manager will only accept connections from the local machine.
171 This mode is only useful for testing Flumotion.
172 """)
173 start_worker_check = None
174 next_pages = ['start_new_error', 'start_new_success']
175 gsignal('finished', str)
176
177 _timeout_id = None
178
181
183 self.label_starting.show()
184 self.progressbar_starting.set_fraction(0.0)
185 self.progressbar_starting.show()
186
187 import socket
188 port = 7531
189 def tryPort(port=0):
190
191
192 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
193 self.debug('Binding to port %d' % port)
194
195 try:
196 s.bind(('', port))
197 port = s.getsockname()[1]
198 except socket.error, e:
199 if e.args[0] == errno.EADDRINUSE:
200 self.debug('Port %d already in use', port)
201 port = None
202
203 s.close()
204 return port
205
206 if tryPort(port) is None:
207 port = tryPort()
208
209
210
211 def pulse():
212 self.progressbar_starting.pulse()
213 return True
214
215 self._timeout_id = gobject.timeout_add(200, pulse)
216
217 import tempfile
218 path = tempfile.mkdtemp(suffix='.flumotion')
219 confDir = os.path.join(path, 'etc')
220 logDir = os.path.join(path, 'var', 'log')
221 runDir = os.path.join(path, 'var', 'run')
222
223
224 d = defer.Deferred()
225 def run(result, args, description, failMessage):
226
227
228 self.label_starting.set_text(description)
229 args[0] = os.path.join(configure.sbindir, args[0])
230 protocol = GreeterProcessProtocol()
231 env = os.environ.copy()
232 paths = env['PATH'].split(os.pathsep)
233 if configure.bindir not in paths:
234 paths.insert(0, configure.bindir)
235 env['PATH'] = os.pathsep.join(paths)
236 process = reactor.spawnProcess(protocol, args[0], args, env=env)
237 def error(failure, failMessage):
238 self.label_starting.set_text('Failed to %s' % description)
239
240 state.update({
241 'command': ' '.join(args),
242 'error': failMessage,
243 'failure': failure,
244 })
245 self.finished('start_new_error')
246 return failure
247 protocol.deferred.addErrback(error, failMessage)
248 return protocol.deferred
249
250 def chain(args, description, failMessage):
251 d.addCallback(run, args, description, failMessage)
252
253 chain(["flumotion", "-C", confDir, "-L", logDir, "-R", runDir,
254 "create", "manager", "admin", str(port)],
255 _('Creating manager ...'),
256 _("Could not create manager."))
257
258 chain(["flumotion", "-C", confDir, "-L", logDir, "-R", runDir,
259 "start", "manager", "admin"],
260 _('Starting manager ...'),
261 _("Could not start manager."))
262
263 chain(["flumotion", "-C", confDir, "-L", logDir, "-R", runDir,
264 "create", "worker", "admin", str(port)],
265 _('Creating worker ...'),
266 _("Could not create worker."))
267
268 chain(["flumotion", "-C", confDir, "-L", logDir, "-R", runDir,
269 "start", "worker", "admin"],
270 _('Starting worker ...'),
271 _("Could not start worker."))
272
273 d.addErrback(lambda f: None)
274
275 def done(result, state):
276
277
278 state.update({
279 'host': 'localhost',
280 'port': port,
281 'use_insecure': False,
282 'user': 'user',
283 'passwd': 'test',
284 'confDir': confDir,
285 'logDir': logDir,
286 'runDir': runDir,
287 })
288 self.finished('start_new_success')
289
290 d.addCallback(done, state)
291
292
293 d.callback(None)
294 return '*signaled*'
295
297
298 self.label_starting.hide()
299 self.progressbar_starting.hide()
300 gobject.source_remove(self._timeout_id)
301 self.emit('finished', result)
302
304 name = 'start_new_error'
305 title = _('Failed to start')
306 text = ""
307 start_worker_check = None
308 next_pages = []
309
310 - def setup(self, state, available_pages):
311 self.button_next.set_sensitive(False)
312 self.message.set_text(state['error'])
313 f = state['failure']
314 result = ""
315 if f.value.exitCode is not None:
316 result = _('The command exited with an exit code of %d.' %
317 f.value.exitCode)
318 self.more.set_markup(_("""The command that failed was:
319 <i>%s</i>
320 %s""") % (state['command'], result))
321
322
324 name = 'start_new_success'
325 title = _('Started manager and worker')
326 start_worker_check = None
327 text = ''
328 next_pages = []
329
330 - def setup(self, state, available_pages):
331 executable = os.path.join(configure.sbindir, 'flumotion')
332 confDir = state['confDir']
333 logDir = state['logDir']
334 runDir = state['runDir']
335 stop = "%s -C %s -L %s -R %s stop" % (
336 executable, confDir, logDir, runDir)
337 self.message.set_markup(_(
338 """The admin client will now connect to the manager.
339
340 Configuration files are stored in
341 <i>%s</i>
342 Log files are stored in
343 <i>%s</i>
344
345 You can shut down the manager and worker later with the following command:
346
347 <i>%s</i>
348 """) % (confDir, logDir, stop))
349
352
353
361