204
226
# The password for the usrmgt-server.""", ask=False))
206
def query_user(default, prompt):
207
"""Prompts the user for a string, which is read from a line of stdin.
208
Exits silently if EOF is encountered. Returns the string, with spaces
209
removed from the beginning and end.
211
Returns default if a 0-length line (after spaces removed) was read.
214
# A default of None means the value will be computed specially, so we
215
# can't really tell you what it is
216
defaultstr = "computed"
217
elif isinstance(default, basestring):
218
defaultstr = '"%s"' % default
220
defaultstr = repr(default)
221
sys.stdout.write('%s\n (default: %s)\n>' % (prompt, defaultstr))
223
val = sys.stdin.readline()
224
except KeyboardInterrupt:
226
sys.stdout.write("\n")
228
sys.stdout.write("\n")
230
if val == '': sys.exit(1)
231
# If empty line, return default
233
if val == '': return default
236
228
def configure(args):
229
# Call the real function
230
return __configure(args)
232
def __configure(args):
237
233
# Try importing existing conf, but if we can't just set up defaults
238
234
# The reason for this is that these settings are used by other phases
239
235
# of setup besides conf, so we need to know them.
240
236
# Also this allows you to hit Return to accept the existing value.
242
conf = ivle.config.Config()
243
except ivle.config.ConfigError:
244
# Couldn't find a config file anywhere.
245
# Create a new blank config object (not yet bound to a file)
246
# All lookups (below) will fail, so it will be initialised with all
247
# the default values.
248
conf = ivle.config.Config(blank=True)
250
# Check that all the options are present, and if not, load the default
237
conf = ivle.config.Config()
251
238
for opt in config_options:
253
conf.get_by_path(opt.option_name)
240
conf_options[opt.option_name] = conf.get_by_path(opt.option_name)
255
# If the default is None, omit it
256
# Else ConfigObj will write the string 'None' to the conf file
257
if opt.default is not None:
258
conf.set_by_path(opt.option_name, opt.default)
260
# Store comments in the conf object
261
for opt in config_options:
262
# Omitted if the key doesn't exist
263
conf.set_by_path(opt.option_name, comment=opt.comment)
242
conf_options[opt.option_name] = opt.default
265
244
# Set up some variables
266
245
cwd = os.getcwd()
268
247
# the files that will be created/overwritten
270
confdir = os.environ['IVLECONF']
272
confdir = '/etc/ivle'
274
conffile = os.path.join(confdir, 'ivle.conf')
275
plugindefaultfile = os.path.join(confdir, 'plugins.d/000default.conf')
248
conffile = os.path.join(cwd, "etc/ivle.conf")
249
conf_hfile = os.path.join(cwd, "bin/trampoline/conf.h")
250
phpBBconffile = os.path.join(cwd, "www/php/phpBB3/config.php")
277
252
# Get command-line arguments to avoid asking questions.
305
280
for opt in config_options:
307
conf.set_by_path(opt.option_name,
308
query_user(conf.get_by_path(opt.option_name), opt.prompt))
282
conf_options[opt.option_name] = \
283
query_user(conf_options[opt.option_name], opt.prompt)
310
285
opts = dict(opts)
311
286
# Non-interactive mode. Parse the options.
312
287
for opt in config_options:
313
288
if '--' + opt.option_name in opts:
314
conf.set_by_path(opt.option_name,
315
opts['--' + opt.option_name])
289
conf_options[opt.option_name] = opts['--' + opt.option_name]
317
291
# Error handling on input values
319
conf['database']['port'] = int(conf['database']['port'])
320
if (conf['database']['port'] < 0
321
or conf['database']['port'] >= 65536):
293
allowed_uids_list = map(int,
294
conf_options['os/allowed_uids'].split(','))
296
print >>sys.stderr, (
297
"Invalid UID list (%s).\n"
298
"Must be a comma-separated list of integers." %
299
conf_options['os/allowed_uids'])
302
conf_options['database/port'] = int(conf_options['database/port'])
303
if (conf_options['database/port'] < 0
304
or conf_options['database/port'] >= 65536):
322
305
raise ValueError()
323
306
except ValueError:
324
if conf['database']['port'] == '' or conf['database']['port'] is None:
327
print >>sys.stderr, (
328
"Invalid DB port (%s).\n"
329
"Must be an integer between 0 and 65535." %
330
repr(conf['database']['port']))
307
print >>sys.stderr, (
308
"Invalid DB port (%s).\n"
309
"Must be an integer between 0 and 65535." %
310
repr(conf_options['database/port']))
333
conf['usrmgt']['port'] = int(conf['usrmgt']['port'])
334
if (conf['usrmgt']['port'] < 0 or conf['usrmgt']['port'] >= 65536):
313
conf_options['usrmgt/port'] = int(conf_options['usrmgt/port'])
314
if (conf_options['usrmgt/port'] < 0
315
or conf_options['usrmgt/port'] >= 65536):
335
316
raise ValueError()
336
317
except ValueError:
337
318
print >>sys.stderr, (
338
319
"Invalid user management port (%s).\n"
339
320
"Must be an integer between 0 and 65535." %
340
repr(conf['usrmgt']['port']))
321
repr(conf_options['usrmgt/port']))
343
324
# By default we generate the magic randomly.
345
conf['usrmgt']['magic'] # Throw away; just check for KeyError
347
conf['usrmgt']['magic'] = hashlib.md5(uuid.uuid4().bytes).hexdigest()
349
clobber_permissions = not os.path.exists(conffile)
351
# Write ./etc/ivle.conf (even if we loaded from a different filename)
325
if conf_options['usrmgt/magic'] is None:
326
conf_options['usrmgt/magic'] = \
327
hashlib.md5(uuid.uuid4().bytes).hexdigest()
329
# Generate the forum secret
330
forum_secret = hashlib.md5(uuid.uuid4().bytes).hexdigest()
332
# Write ./etc/ivle.conf
334
conf = ivle.config.Config(blank=True)
352
335
conf.filename = conffile
353
337
conf.initial_comment = ["# IVLE Configuration File"]
339
# Add the forum secret to the config file (regenerated each config)
340
config_options.append(ConfigOption('plugins/forum/secret', None, '', ''))
341
conf_options['plugins/forum/secret'] = forum_secret
343
for opt in config_options:
344
newopt_path = opt.option_name.split('/')
345
# Iterate over each segment of the path, and find the section in conf
346
# file to insert the value into (use all but the last path segment)
348
for seg in newopt_path[:-1]:
349
# Create the section if it isn't there
350
if seg not in conf_section:
351
conf_section[seg] = {}
352
conf_section = conf_section[seg]
353
# The final path segment names the key to insert into
354
keyname = newopt_path[-1]
355
value = conf_options[opt.option_name]
356
if value is not None:
357
conf_section[keyname] = value
358
conf_section.comments[keyname] = opt.comment.split('\n')
356
# We need to restrict permissions on a new file, as it contains
357
# a nice database password.
358
if clobber_permissions:
359
os.chown(conffile, 33, 33) # chown to www-data
360
os.chmod(conffile, stat.S_IRUSR | stat.S_IWUSR) # No g/o perms!
362
362
print "Successfully wrote %s" % conffile
364
plugindefault = open(plugindefaultfile, 'w')
365
plugindefault.write("""# IVLE default plugin configuration file
366
[ivle.webapp.core#Plugin]
367
[ivle.webapp.admin.user#Plugin]
368
[ivle.webapp.tutorial#Plugin]
369
[ivle.webapp.admin.subject#Plugin]
370
[ivle.webapp.filesystem.browser#Plugin]
371
[ivle.webapp.filesystem.diff#Plugin]
372
[ivle.webapp.filesystem.svnlog#Plugin]
373
[ivle.webapp.filesystem.serve#Plugin]
374
[ivle.webapp.groups#Plugin]
375
[ivle.webapp.console#Plugin]
376
[ivle.webapp.security#Plugin]
377
[ivle.webapp.media#Plugin]
378
[ivle.webapp.help#Plugin]
379
[ivle.webapp.tos#Plugin]
380
[ivle.webapp.userservice#Plugin]
381
[ivle.webapp.fileservice#Plugin]
382
[ivle.webapp.submit#Plugin]
384
plugindefault.close()
385
print "Successfully wrote %s" % plugindefaultfile
388
print "You may modify the configuration at any time by editing " + conffile
364
# Write bin/trampoline/conf.h
366
conf = open(conf_hfile, "w")
368
# XXX Compute jail_base, jail_src_base and jail_system. These will
369
# ALSO be done by the boilerplate code, but we need them here in order
370
# to write to the C file.
371
jail_base = os.path.join(conf_options['paths/data'], 'jailmounts')
372
jail_src_base = os.path.join(conf_options['paths/data'], 'jails')
373
jail_system = os.path.join(jail_src_base, '__base__')
375
conf.write("""/* IVLE Configuration File
377
* Administrator settings required by trampoline.
378
* Note: trampoline will have to be rebuilt in order for changes to this file
382
#define IVLE_AUFS_JAILS
384
/* In the local file system, where are the jails located.
385
* The trampoline does not allow the creation of a jail anywhere besides
386
* jail_base or a subdirectory of jail_base.
388
static const char* jail_base = "%s";
389
static const char* jail_src_base = "%s";
390
static const char* jail_system = "%s";
392
/* Which user IDs are allowed to run the trampoline.
393
* This list should be limited to the web server user.
394
* (Note that root is an implicit member of this list).
396
static const int allowed_uids[] = { %s };
397
""" % (repr(jail_base)[1:-1], repr(jail_src_base)[1:-1],
398
repr(jail_system)[1:-1], repr(allowed_uids_list)[1:-1]))
399
# Note: The above uses PYTHON reprs, not C reprs
400
# However they should be the same with the exception of the outer
401
# characters, which are stripped off and replaced
405
print "Successfully wrote %s" % conf_hfile
407
# Write www/php/phpBB3/config.php
409
conf = open(phpBBconffile, "w")
412
if conf_options['database/host'] == 'localhost':
413
forumdb_host = '127.0.0.1'
415
forumdb_host = conf_options['database/host']
418
// phpBB 3.0.x auto-generated configuration file
419
// Do not change anything in this file!
421
$dbhost = '""" + forumdb_host + """';
422
$dbport = '""" + str(conf_options['database/port']) + """';
423
$dbname = '""" + conf_options['plugins/forum/dbname'] + """';
424
$dbuser = '""" + conf_options['database/username'] + """';
425
$dbpasswd = '""" + conf_options['database/password'] + """';
427
$table_prefix = 'phpbb_';
429
$load_extensions = '';
430
@define('PHPBB_INSTALLED', true);
431
// @define('DEBUG', true);
432
//@define('DEBUG_EXTRA', true);
434
$forum_secret = '""" + forum_secret +"""';
439
print "Successfully wrote %s" % phpBBconffile
442
print "You may modify the configuration at any time by editing"
396
# Print the opening spiel including the GPL notice
398
print """IVLE - Informatics Virtual Learning Environment Setup
399
Copyright (C) 2007-2009 The University of Melbourne
400
IVLE comes with ABSOLUTELY NO WARRANTY.
401
This is free software, and you are welcome to redistribute it
402
under certain conditions. See LICENSE.txt for details.
407
return configure(argv[1:])
409
if __name__ == "__main__":