~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to setup/configure.py

Added config validation spec: ivle/config/ivle-spec.conf.
ivle.conf.conf: No longer needs to do the cast-to-int hack.
ivle.config: Runs against the validator (with a XXX problem).
setup.util: ivle-spec.conf is installed with a new whitelist.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# IVLE - Informatics Virtual Learning Environment
2
 
# Copyright (C) 2007-2008 The University of Melbourne
 
2
# Copyright (C) 2007-2009 The University of Melbourne
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
5
5
# it under the terms of the GNU General Public License as published by
19
19
# Author: Matt Giuca, Refactored by David Coles
20
20
# Date:   03/07/2008
21
21
 
22
 
# setup/config.py
23
 
# Configures IVLE with machine-specific details, most notably, various paths.
24
 
# Either prompts the administrator for these details or accepts them as
25
 
# command-line args.
26
 
# Creates lib/conf/conf.py and bin/trampoline/conf.h.
 
22
'''Configures IVLE with machine-specific details, most notably, various paths.
 
23
Either prompts the administrator for these details or accepts them as
 
24
command-line args.
 
25
 
 
26
Creates ivle/conf/conf.py and bin/trampoline/trampoline/conf.h.
 
27
'''
27
28
 
28
29
import optparse
29
30
import getopt
34
35
 
35
36
from setup.util import query_user
36
37
 
 
38
import configobj
 
39
 
 
40
# This dict maps legacy config option names to new config option paths
 
41
# ('section/option_name')
 
42
# NOTE: This is copied from ivle/conf/conf.py (because neither of these files
 
43
# can see each other).
 
44
CONFIG_OPTIONS = {
 
45
    'root_dir': 'urls/root',
 
46
    'prefix': 'paths/prefix',
 
47
    'data_path': 'paths/data',
 
48
    'log_path': 'paths/logs',
 
49
    'python_site_packages_override': 'paths/site_packages',
 
50
    'public_host': 'urls/public_host',
 
51
    'allowed_uids': 'os/allowed_uids',
 
52
    'db_host': 'database/host',
 
53
    'db_port': 'database/port',
 
54
    'db_dbname': 'database/name',
 
55
    'db_forumdbname': 'plugins/forum/dbname',
 
56
    'db_user': 'database/username',
 
57
    'db_password': 'database/password',
 
58
    'auth_modules': 'auth/modules',
 
59
    'ldap_url': 'auth/ldap_url',
 
60
    'ldap_format_string': 'auth/ldap_format_string',
 
61
    'subject_pulldown_modules': 'auth/subject_pulldown_modules',
 
62
    'svn_addr': 'urls/svn_addr',
 
63
    'usrmgt_host': 'usrmgt/host',
 
64
    'usrmgt_port': 'usrmgt/port',
 
65
    'usrmgt_magic': 'usrmgt/magic',
 
66
    'forum_secret': 'plugins/forum/secret',
 
67
}
 
68
 
37
69
class ConfigOption:
38
70
    """A configuration option; one of the things written to conf.py."""
39
71
    def __init__(self, option_name, default, prompt, comment, ask=True):
127
159
==========================
128
160
Hostname of the DB server:""",
129
161
    """
130
 
### PostgreSQL Database config ###
131
162
# Database server hostname"""))
132
163
 
133
164
config_options.append(ConfigOption("db_port", "5432",
220
251
# The password for the usrmgt-server.""", ask=False))
221
252
 
222
253
def configure(args):
223
 
    usage = """usage: %prog config [options]
224
 
Creates lib/conf/conf.py (and a few other config files).
225
 
Interactively asks questions to set this up."""
226
 
 
227
 
    # Parse arguments
228
 
    parser = optparse.OptionParser(usage)
229
 
    (options, args) = parser.parse_args(args)
230
 
 
231
254
    # Call the real function
232
255
    return __configure(args)
233
256
 
255
278
    cwd = os.getcwd()
256
279
 
257
280
    # the files that will be created/overwritten
258
 
    conffile = os.path.join(cwd, "ivle/conf/conf.py")
259
 
    jailconffile = os.path.join(cwd, "ivle/conf/jailconf.py")
 
281
    conffile = os.path.join(cwd, "etc/ivle.conf")
260
282
    conf_hfile = os.path.join(cwd, "bin/trampoline/conf.h")
261
283
    phpBBconffile = os.path.join(cwd, "www/php/phpBB3/config.php")
262
284
 
278
300
    %s
279
301
    %s
280
302
    %s
281
 
    %s
282
303
prompting you for details about your configuration. The file will be
283
304
overwritten if it already exists. It will *not* install or deploy IVLE.
284
305
 
285
306
Please hit Ctrl+C now if you do not wish to do this.
286
 
""" % (conffile, jailconffile, conf_hfile, phpBBconffile)
 
307
""" % (conffile, conf_hfile, phpBBconffile)
287
308
 
288
309
        # Get information from the administrator
289
310
        # If EOF is encountered at any time during the questioning, just exit
332
353
    # Generate the forum secret
333
354
    forum_secret = hashlib.md5(uuid.uuid4().bytes).hexdigest()
334
355
 
335
 
    # Write lib/conf/conf.py
336
 
 
337
 
    try:
338
 
        conf = open(conffile, "w")
339
 
 
340
 
        conf.write("""# IVLE Configuration File
341
 
# conf.py
342
 
# Miscellaneous application settings
343
 
 
344
 
import os
345
 
import sys
346
 
""")
347
 
        for opt in config_options:
348
 
            conf.write('%s\n%s = %r\n' % (opt.comment, opt.option_name,
349
 
                globals()[opt.option_name]))
350
 
 
351
 
            # Add the forum secret to the config file (regenerated each config)
352
 
        conf.write('forum_secret = "%s"\n\n' % (forum_secret))
353
 
 
354
 
        write_conf_file_boilerplate(conf)
355
 
 
356
 
        conf.close()
357
 
    except IOError, (errno, strerror):
358
 
        print "IO error(%s): %s" % (errno, strerror)
359
 
        sys.exit(1)
 
356
    # Write ./etc/ivle.conf
 
357
 
 
358
    conf = configobj.ConfigObj()
 
359
    conf.filename = conffile
 
360
 
 
361
    conf.initial_comment = ["# IVLE Configuration File"]
 
362
 
 
363
    # Add the forum secret to the config file (regenerated each config)
 
364
    config_options.append(ConfigOption('forum_secret', None, '', ''))
 
365
    globals()['forum_secret'] = forum_secret
 
366
 
 
367
    for legacyopt in config_options:
 
368
        newopt_path = CONFIG_OPTIONS[legacyopt.option_name].split('/')
 
369
        # Iterate over each segment of the path, and find the section in conf
 
370
        # file to insert the value into (use all but the last path segment)
 
371
        conf_section = conf
 
372
        for seg in newopt_path[:-1]:
 
373
            # Create the section if it isn't there
 
374
            if seg not in conf_section:
 
375
                conf_section[seg] = {}
 
376
            conf_section = conf_section[seg]
 
377
        # The final path segment names the key to insert into
 
378
        keyname = newopt_path[-1]
 
379
        value = globals()[legacyopt.option_name]
 
380
        if value is not None:
 
381
            conf_section[keyname] = value
 
382
            conf_section.comments[keyname] = legacyopt.comment.split('\n')
 
383
 
 
384
    conf.write()
360
385
 
361
386
    print "Successfully wrote %s" % conffile
362
387
 
363
 
    # Write conf/jailconf.py
364
 
 
365
 
    try:
366
 
        conf = open(jailconffile, "w")
367
 
 
368
 
        # In the "in-jail" version of conf, we don't need MOST of the details
369
 
        # (it would be a security risk to have them here).
370
 
        # So we just write root_dir, and jail_base is "/".
371
 
        # (jail_base being "/" means "jail-relative" paths are relative to "/"
372
 
        # when inside the jail.)
373
 
        conf.write("""# IVLE Configuration File
374
 
# conf.py
375
 
# Miscellaneous application settings
376
 
# (User jail version)
377
 
 
378
 
 
379
 
# In URL space, where in the site is IVLE located. (All URLs will be prefixed
380
 
# with this).
381
 
# eg. "/" or "/ivle".
382
 
root_dir = %s
383
 
 
384
 
# In the local file system, where are the student/user file spaces located.
385
 
# The user jails are expected to be located immediately in subdirectories of
386
 
# this location.
387
 
jail_base = '/'
388
 
 
389
 
# The hostname for serving publicly accessible pages
390
 
public_host = %s
391
 
 
392
 
# The URL under which the Subversion repositories are located.
393
 
svn_addr = %s
394
 
""" % (repr(root_dir),repr(public_host),repr(svn_addr)))
395
 
 
396
 
        conf.close()
397
 
    except IOError, (errno, strerror):
398
 
        print "IO error(%s): %s" % (errno, strerror)
399
 
        sys.exit(1)
400
 
 
401
 
    print "Successfully wrote %s" % jailconffile
402
 
 
403
388
    # Write bin/trampoline/conf.h
404
389
 
405
 
    try:
406
 
        conf = open(conf_hfile, "w")
407
 
 
408
 
        # XXX Compute jail_base, jail_src_base and jail_system. These will
409
 
        # ALSO be done by the boilerplate code, but we need them here in order
410
 
        # to write to the C file.
411
 
        jail_base = os.path.join(data_path, 'jailmounts')
412
 
        jail_src_base = os.path.join(data_path, 'jails')
413
 
        jail_system = os.path.join(jail_src_base, '__base__')
414
 
 
415
 
        conf.write("""/* IVLE Configuration File
 
390
    conf = open(conf_hfile, "w")
 
391
 
 
392
    # XXX Compute jail_base, jail_src_base and jail_system. These will
 
393
    # ALSO be done by the boilerplate code, but we need them here in order
 
394
    # to write to the C file.
 
395
    jail_base = os.path.join(data_path, 'jailmounts')
 
396
    jail_src_base = os.path.join(data_path, 'jails')
 
397
    jail_system = os.path.join(jail_src_base, '__base__')
 
398
 
 
399
    conf.write("""/* IVLE Configuration File
416
400
 * conf.h
417
401
 * Administrator settings required by trampoline.
418
402
 * Note: trampoline will have to be rebuilt in order for changes to this file
440
424
    # However they should be the same with the exception of the outer
441
425
    # characters, which are stripped off and replaced
442
426
 
443
 
        conf.close()
444
 
    except IOError, (errno, strerror):
445
 
        print "IO error(%s): %s" % (errno, strerror)
446
 
        sys.exit(1)
 
427
    conf.close()
447
428
 
448
429
    print "Successfully wrote %s" % conf_hfile
449
430
 
450
431
    # Write www/php/phpBB3/config.php
451
432
 
452
 
    try:
453
 
        conf = open(phpBBconffile, "w")
454
 
        
455
 
        # php-pg work around
456
 
        if db_host == 'localhost':
457
 
            forumdb_host = '127.0.0.1'
458
 
        else:
459
 
            forumdb_host = db_host
 
433
    conf = open(phpBBconffile, "w")
 
434
    
 
435
    # php-pg work around
 
436
    if db_host == 'localhost':
 
437
        forumdb_host = '127.0.0.1'
 
438
    else:
 
439
        forumdb_host = db_host
460
440
 
461
 
        conf.write( """<?php
 
441
    conf.write( """<?php
462
442
// phpBB 3.0.x auto-generated configuration file
463
443
// Do not change anything in this file!
464
444
$dbms = 'postgres';
478
458
$forum_secret = '""" + forum_secret +"""';
479
459
?>"""   )
480
460
    
481
 
        conf.close()
482
 
    except IOError, (errno, strerror):
483
 
        print "IO error(%s): %s" % (errno, strerror)
484
 
        sys.exit(1)
 
461
    conf.close()
485
462
 
486
463
    print "Successfully wrote %s" % phpBBconffile
487
464
 
488
465
    print
489
466
    print "You may modify the configuration at any time by editing"
490
467
    print conffile
491
 
    print jailconffile
492
468
    print conf_hfile
493
469
    print phpBBconffile
494
470
    print
495
471
    
496
472
    return 0
497
 
 
498
 
def write_conf_file_boilerplate(conf_file):
499
 
    conf_file.write("""\
500
 
### Below is boilerplate code, appended by ./setup.py config ###
501
 
 
502
 
# Path where architecture-dependent data (including non-user-executable
503
 
# binaries) is installed.
504
 
lib_path = os.path.join(prefix, 'lib/ivle')
505
 
 
506
 
# Path where arch-independent data is installed.
507
 
share_path = os.path.join(prefix, 'share/ivle')
508
 
 
509
 
# Path where user-executable binaries are installed.
510
 
bin_path = os.path.join(prefix, 'bin')
511
 
 
512
 
# 'site-packages' directory in Python, where Python libraries are to be
513
 
# installed.
514
 
if python_site_packages_override is None:
515
 
    PYTHON_VERSION = sys.version[0:3]   # eg. "2.5"
516
 
    python_site_packages = os.path.join(prefix,
517
 
                               'lib/python%s/site-packages' % PYTHON_VERSION)
518
 
else:
519
 
    python_site_packages = python_site_packages_override
520
 
 
521
 
# In the local file system, where the student/user jails will be mounted.
522
 
# Only a single copy of the jail's system components will be stored here -
523
 
# all user jails will be virtually mounted here.
524
 
jail_base = os.path.join(data_path, 'jailmounts')
525
 
 
526
 
# In the local file system, where are the student/user file spaces located.
527
 
# The user jails are expected to be located immediately in subdirectories of
528
 
# this location. Note that no complete jails reside here - only user
529
 
# modifications.
530
 
jail_src_base = os.path.join(data_path, 'jails')
531
 
 
532
 
# In the local file system, where the template system jail will be stored.
533
 
jail_system = os.path.join(jail_src_base, '__base__')
534
 
 
535
 
# In the local file system, where the subject content files are located.
536
 
# (The 'subjects' and 'exercises' directories).
537
 
content_path = os.path.join(data_path, 'content')
538
 
 
539
 
# In the local file system, where are the per-subject file spaces located.
540
 
# The individual subject directories are expected to be located immediately
541
 
# in subdirectories of this location.
542
 
subjects_base = os.path.join(content_path, 'subjects')
543
 
 
544
 
# In the local file system, where are the subject-independent exercise sheet
545
 
# file spaces located.
546
 
exercises_base = os.path.join(content_path, 'exercises')
547
 
 
548
 
# In the local file system, where the system notices are stored (such as terms
549
 
# of service and MOTD).
550
 
notices_path = os.path.join(data_path, 'notices')
551
 
 
552
 
# In the local file system, where is the Terms of Service document located.
553
 
tos_path = os.path.join(notices_path, 'tos.html')
554
 
 
555
 
# In the local file system, where is the Message of the Day document
556
 
# located. This is an HTML file (just the body fragment), which will
557
 
# be displayed on the login page. It is optional.
558
 
motd_path = os.path.join(notices_path, 'motd.html')
559
 
 
560
 
# The location of all the subversion config and repositories.
561
 
svn_path = os.path.join(data_path, 'svn')
562
 
 
563
 
# The location of the subversion configuration file used by
564
 
# apache to host the user repositories.
565
 
svn_conf = os.path.join(svn_path, 'svn.conf')
566
 
 
567
 
# The location of the subversion configuration file used by
568
 
# apache to host the user repositories.
569
 
svn_group_conf = os.path.join(svn_path, 'svn-group.conf')
570
 
 
571
 
# The root directory for the subversion repositories.
572
 
svn_repo_path = os.path.join(svn_path, 'repositories')
573
 
 
574
 
# The location of the password file used to authenticate users
575
 
# of the subversion repository from the ivle server.
576
 
svn_auth_ivle = os.path.join(svn_path, 'ivle.auth')
577
 
""")