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

« back to all changes in this revision

Viewing changes to setup/configure.py

  • Committer: chadnickbok
  • Date: 2009-02-02 04:00:25 UTC
  • Revision ID: svn-v4:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1189
Adding the changes from my genshi branch into trunk.

Most apps now use the Genshi templating engine, in preparation
for future changes to dispatch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# IVLE - Informatics Virtual Learning Environment
2
 
# Copyright (C) 2007-2009 The University of Melbourne
 
2
# Copyright (C) 2007-2008 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
 
'''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
 
'''
 
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.
28
27
 
29
28
import optparse
30
29
import getopt
34
33
import uuid
35
34
 
36
35
from setup.util import query_user
37
 
import ivle.config
38
 
 
39
 
import configobj
40
 
 
41
 
# conf_options maps option names to values
42
 
conf_options = {}
43
36
 
44
37
class ConfigOption:
45
38
    """A configuration option; one of the things written to conf.py."""
63
56
# Configuration options, defaults and descriptions
64
57
config_options = []
65
58
 
66
 
config_options.append(ConfigOption("urls/root", "/",
 
59
config_options.append(ConfigOption("root_dir", "/",
67
60
    """Root directory where IVLE is located (in URL space):""",
68
61
    """
69
62
# In URL space, where in the site is IVLE located. (All URLs will be prefixed
70
63
# with this).
71
64
# eg. "/" or "/ivle".""", ask=False))
72
65
 
73
 
config_options.append(ConfigOption("paths/prefix", "/usr/local",
 
66
config_options.append(ConfigOption("prefix", "/usr/local",
74
67
    """In the local file system, the prefix to the system directory where IVLE
75
68
is installed. (This should either be /usr or /usr/local):""",
76
69
    """
79
72
# ('/usr/local' for the usual install, '/usr' for distribution packages)""",
80
73
    ask=False))
81
74
 
82
 
config_options.append(ConfigOption("paths/site_packages",
 
75
config_options.append(ConfigOption("python_site_packages_override",
83
76
    None,
84
77
    """site-packages directory in Python, where Python libraries are to be
85
78
installed. May be left as the default, in which case the value will be
89
82
# installed. May be None (recommended), in which case the value will be
90
83
# computed from prefix and the current Python version.""", ask=False))
91
84
 
92
 
config_options.append(ConfigOption("paths/data",
 
85
config_options.append(ConfigOption("data_path",
93
86
    "/var/lib/ivle",
94
87
    "In the local file system, where user-modifiable data files should be "
95
88
    "located:",
97
90
# In the local file system, where user-modifiable data files should be
98
91
# located.""", ask=False))
99
92
 
100
 
config_options.append(ConfigOption("paths/logs",
 
93
config_options.append(ConfigOption("log_path",
101
94
    "/var/log/ivle",
102
95
    """Directory where IVLE log files are stored (on the local
103
96
file system). Note - this must be writable by the user the IVLE server 
106
99
# In the local file system, where IVLE error logs should be located.""",
107
100
    ask=False))
108
101
 
109
 
config_options.append(ConfigOption("urls/public_host", "public.localhost",
 
102
config_options.append(ConfigOption("public_host", "public.localhost",
110
103
    """Hostname which will cause the server to go into "public mode",
111
104
providing login-free access to student's published work:""",
112
105
    """
117
110
# Private mode (normal mode) requires login, and only serves files relevant to
118
111
# the logged-in user."""))
119
112
 
120
 
config_options.append(ConfigOption("os/allowed_uids", "33",
 
113
config_options.append(ConfigOption("allowed_uids", "33",
121
114
    """UID of the web server process which will run IVLE.
122
115
Only this user may execute the trampoline. May specify multiple users as
123
116
a comma-separated list.
129
122
# used by the setup program to write to conf.h (see setup.py config).""",
130
123
    ask=False))
131
124
 
132
 
config_options.append(ConfigOption("database/host", "localhost",
 
125
config_options.append(ConfigOption("db_host", "localhost",
133
126
    """PostgreSQL Database config
134
127
==========================
135
128
Hostname of the DB server:""",
136
129
    """
 
130
### PostgreSQL Database config ###
137
131
# Database server hostname"""))
138
132
 
139
 
config_options.append(ConfigOption("database/port", "5432",
 
133
config_options.append(ConfigOption("db_port", "5432",
140
134
    """Port of the DB server:""",
141
135
    """
142
136
# Database server port"""))
143
137
 
144
 
config_options.append(ConfigOption("database/name", "ivle",
 
138
config_options.append(ConfigOption("db_dbname", "ivle",
145
139
    """Database name:""",
146
140
    """
147
141
# Database name"""))
148
142
 
149
 
config_options.append(ConfigOption("plugins/forum/dbname", "ivle_forum",
 
143
config_options.append(ConfigOption("db_forumdbname", "ivle_forum",
150
144
    """Forum Database name:""",
151
145
    """
152
146
# Forum Database name"""))
153
147
 
154
 
config_options.append(ConfigOption("database/username", "postgres",
 
148
config_options.append(ConfigOption("db_user", "postgres",
155
149
    """Username for DB server login:""",
156
150
    """
157
151
# Database username"""))
158
152
 
159
 
config_options.append(ConfigOption("database/password", "",
 
153
config_options.append(ConfigOption("db_password", "",
160
154
    """Password for DB server login:
161
155
    (Caution: This password is stored in plaintext in ivle/conf/conf.py)""",
162
156
    """
163
157
# Database password"""))
164
158
 
165
 
config_options.append(ConfigOption("auth/modules", "",
 
159
config_options.append(ConfigOption("auth_modules", "",
166
160
    """Authentication config
167
161
=====================
168
162
Comma-separated list of authentication modules.""",
176
170
# other modules may be plugged in to auth against organisation-specific
177
171
# auth backends.""", ask=False))
178
172
 
179
 
config_options.append(ConfigOption("auth/ldap_url", "ldaps://www.example.com",
 
173
config_options.append(ConfigOption("ldap_url", "ldaps://www.example.com",
180
174
    """(LDAP options are only relevant if "ldap" is included in the list of
181
175
auth modules).
182
176
URL for LDAP authentication server:""",
183
177
    """
184
178
# URL for LDAP authentication server""", ask=False))
185
179
 
186
 
config_options.append(ConfigOption("auth/ldap_format_string",
 
180
config_options.append(ConfigOption("ldap_format_string",
187
181
    "uid=%s,ou=users,o=example",
188
182
    """Format string for LDAP auth request:
189
183
    (Must contain a single "%s" for the user's login name)""",
191
185
# Format string for LDAP auth request
192
186
# (Must contain a single "%s" for the user's login name)""", ask=False))
193
187
 
194
 
config_options.append(ConfigOption("auth/subject_pulldown_modules", "",
 
188
config_options.append(ConfigOption("subject_pulldown_modules", "",
195
189
    """Comma-separated list of subject pulldown modules.
196
190
Add proprietary modules to automatically enrol students in subjects.""",
197
191
    """
201
195
# other modules may be plugged in to pulldown against organisation-specific
202
196
# pulldown backends.""", ask=False))
203
197
 
204
 
config_options.append(ConfigOption("urls/svn_addr", "http://svn.localhost/",
 
198
config_options.append(ConfigOption("svn_addr", "http://svn.localhost/",
205
199
    """Subversion config
206
200
=================
207
201
The base url for accessing subversion repositories:""",
208
202
    """
209
203
# The base url for accessing subversion repositories."""))
210
204
 
211
 
config_options.append(ConfigOption("usrmgt/host", "localhost",
 
205
config_options.append(ConfigOption("usrmgt_host", "localhost",
212
206
    """User Management Server config
213
207
============================
214
208
The hostname where the usrmgt-server runs:""",
215
209
    """
216
210
# The hostname where the usrmgt-server runs."""))
217
211
 
218
 
config_options.append(ConfigOption("usrmgt/port", "2178",
 
212
config_options.append(ConfigOption("usrmgt_port", "2178",
219
213
    """The port where the usrmgt-server runs:""",
220
214
    """
221
215
# The port where the usrmgt-server runs.""", ask=False))
222
216
 
223
 
config_options.append(ConfigOption("usrmgt/magic", None,
 
217
config_options.append(ConfigOption("usrmgt_magic", None,
224
218
    """The password for the usrmgt-server:""",
225
219
    """
226
220
# The password for the usrmgt-server.""", ask=False))
227
221
 
228
222
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
 
229
231
    # Call the real function
230
232
    return __configure(args)
231
233
 
232
234
def __configure(args):
 
235
    global db_port, usrmgt_port
 
236
 
233
237
    # Try importing existing conf, but if we can't just set up defaults
234
238
    # The reason for this is that these settings are used by other phases
235
239
    # of setup besides conf, so we need to know them.
236
240
    # Also this allows you to hit Return to accept the existing value.
237
241
    try:
238
 
        conf = ivle.config.Config()
239
 
    except ivle.config.ConfigError:
240
 
        # Couldn't find a config file anywhere.
241
 
        # Create a new blank config object (not yet bound to a file)
242
 
        # All lookups (below) will fail, so it will be initialised with all
243
 
        # the default values.
244
 
        conf = ivle.config.Config(blank=True)
245
 
 
246
 
    for opt in config_options:
247
 
        try:
248
 
            conf_options[opt.option_name] = conf.get_by_path(opt.option_name)
249
 
        except KeyError:
250
 
            conf_options[opt.option_name] = opt.default
 
242
        confmodule = __import__("ivle/conf/conf")
 
243
        for opt in config_options:
 
244
            try:
 
245
                globals()[opt.option_name] = \
 
246
                confmodule.__dict__[opt.option_name]
 
247
            except:
 
248
                globals()[opt.option_name] = opt.default
 
249
    except ImportError:
 
250
        # Just set reasonable defaults
 
251
        for opt in config_options:
 
252
            globals()[opt.option_name] = opt.default
251
253
 
252
254
    # Set up some variables
253
255
    cwd = os.getcwd()
254
256
 
255
257
    # the files that will be created/overwritten
256
 
    conffile = os.path.join(cwd, "etc/ivle.conf")
 
258
    conffile = os.path.join(cwd, "ivle/conf/conf.py")
 
259
    jailconffile = os.path.join(cwd, "ivle/conf/jailconf.py")
257
260
    conf_hfile = os.path.join(cwd, "bin/trampoline/conf.h")
258
261
    phpBBconffile = os.path.join(cwd, "www/php/phpBB3/config.php")
259
262
 
275
278
    %s
276
279
    %s
277
280
    %s
 
281
    %s
278
282
prompting you for details about your configuration. The file will be
279
283
overwritten if it already exists. It will *not* install or deploy IVLE.
280
284
 
281
285
Please hit Ctrl+C now if you do not wish to do this.
282
 
""" % (conffile, conf_hfile, phpBBconffile)
 
286
""" % (conffile, jailconffile, conf_hfile, phpBBconffile)
283
287
 
284
288
        # Get information from the administrator
285
289
        # If EOF is encountered at any time during the questioning, just exit
287
291
 
288
292
        for opt in config_options:
289
293
            if opt.ask:
290
 
                conf_options[opt.option_name] = \
291
 
                    query_user(conf_options[opt.option_name], opt.prompt)
 
294
                globals()[opt.option_name] = \
 
295
                    query_user(globals()[opt.option_name], opt.prompt)
292
296
    else:
293
297
        opts = dict(opts)
294
298
        # Non-interactive mode. Parse the options.
295
299
        for opt in config_options:
296
300
            if '--' + opt.option_name in opts:
297
 
                conf_options[opt.option_name] = opts['--' + opt.option_name]
 
301
                globals()[opt.option_name] = opts['--' + opt.option_name]
298
302
 
299
303
    # Error handling on input values
300
304
    try:
301
 
        allowed_uids_list = map(int,
302
 
                                conf_options['os/allowed_uids'].split(','))
 
305
        allowed_uids_list = map(int, allowed_uids.split(','))
303
306
    except ValueError:
304
307
        print >>sys.stderr, (
305
308
        "Invalid UID list (%s).\n"
306
 
        "Must be a comma-separated list of integers." %
307
 
            conf_options['os/allowed_uids'])
 
309
        "Must be a comma-separated list of integers." % allowed_uids)
308
310
        return 1
309
311
    try:
310
 
        conf_options['database/port'] = int(conf_options['database/port'])
311
 
        if (conf_options['database/port'] < 0
312
 
            or conf_options['database/port'] >= 65536):
313
 
            raise ValueError()
 
312
        db_port = int(db_port)
 
313
        if db_port < 0 or db_port >= 65536: raise ValueError()
314
314
    except ValueError:
315
315
        print >>sys.stderr, (
316
316
        "Invalid DB port (%s).\n"
317
 
        "Must be an integer between 0 and 65535." %
318
 
            repr(conf_options['database/port']))
 
317
        "Must be an integer between 0 and 65535." % repr(db_port))
319
318
        return 1
320
319
    try:
321
 
        conf_options['usrmgt/port'] = int(conf_options['usrmgt/port'])
322
 
        if (conf_options['usrmgt/port'] < 0
323
 
            or conf_options['usrmgt/port'] >= 65536):
324
 
            raise ValueError()
 
320
        usrmgt_port = int(usrmgt_port)
 
321
        if usrmgt_port < 0 or usrmgt_port >= 65536: raise ValueError()
325
322
    except ValueError:
326
323
        print >>sys.stderr, (
327
324
        "Invalid user management port (%s).\n"
328
 
        "Must be an integer between 0 and 65535." %
329
 
            repr(conf_options['usrmgt/port']))
 
325
        "Must be an integer between 0 and 65535." % repr(usrmgt_port))
330
326
        return 1
331
327
 
332
328
    # By default we generate the magic randomly.
333
 
    if conf_options['usrmgt/magic'] is None:
334
 
        conf_options['usrmgt/magic'] = \
335
 
            hashlib.md5(uuid.uuid4().bytes).hexdigest()
 
329
    if globals()['usrmgt_magic'] is None:
 
330
        globals()['usrmgt_magic'] = hashlib.md5(uuid.uuid4().bytes).hexdigest()
336
331
 
337
332
    # Generate the forum secret
338
333
    forum_secret = hashlib.md5(uuid.uuid4().bytes).hexdigest()
339
334
 
340
 
    # Write ./etc/ivle.conf (even if we loaded from a different filename)
341
 
    conf.filename = conffile
342
 
 
343
 
    conf.initial_comment = ["# IVLE Configuration File"]
344
 
 
345
 
    # Add the forum secret to the config file (regenerated each config)
346
 
    config_options.append(ConfigOption('plugins/forum/secret', None, '', ''))
347
 
    conf_options['plugins/forum/secret'] = forum_secret
348
 
 
349
 
    for opt in config_options:
350
 
        value = conf_options[opt.option_name]
351
 
        if value is not None:
352
 
            conf.set_by_path(opt.option_name, value, opt.comment)
353
 
 
354
 
    conf.write()
 
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)
355
360
 
356
361
    print "Successfully wrote %s" % conffile
357
362
 
 
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
 
358
403
    # Write bin/trampoline/conf.h
359
404
 
360
 
    conf = open(conf_hfile, "w")
361
 
 
362
 
    # XXX Compute jail_base, jail_src_base and jail_system. These will
363
 
    # ALSO be done by the boilerplate code, but we need them here in order
364
 
    # to write to the C file.
365
 
    jail_base = os.path.join(conf_options['paths/data'], 'jailmounts')
366
 
    jail_src_base = os.path.join(conf_options['paths/data'], 'jails')
367
 
    jail_system = os.path.join(jail_src_base, '__base__')
368
 
 
369
 
    conf.write("""/* IVLE Configuration File
 
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
370
416
 * conf.h
371
417
 * Administrator settings required by trampoline.
372
418
 * Note: trampoline will have to be rebuilt in order for changes to this file
394
440
    # However they should be the same with the exception of the outer
395
441
    # characters, which are stripped off and replaced
396
442
 
397
 
    conf.close()
 
443
        conf.close()
 
444
    except IOError, (errno, strerror):
 
445
        print "IO error(%s): %s" % (errno, strerror)
 
446
        sys.exit(1)
398
447
 
399
448
    print "Successfully wrote %s" % conf_hfile
400
449
 
401
450
    # Write www/php/phpBB3/config.php
402
451
 
403
 
    conf = open(phpBBconffile, "w")
404
 
    
405
 
    # php-pg work around
406
 
    if conf_options['database/host'] == 'localhost':
407
 
        forumdb_host = '127.0.0.1'
408
 
    else:
409
 
        forumdb_host = conf_options['database/host']
 
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
410
460
 
411
 
    conf.write( """<?php
 
461
        conf.write( """<?php
412
462
// phpBB 3.0.x auto-generated configuration file
413
463
// Do not change anything in this file!
414
464
$dbms = 'postgres';
415
465
$dbhost = '""" + forumdb_host + """';
416
 
$dbport = '""" + str(conf_options['database/port']) + """';
417
 
$dbname = '""" + conf_options['plugins/forum/dbname'] + """';
418
 
$dbuser = '""" + conf_options['database/username'] + """';
419
 
$dbpasswd = '""" + conf_options['database/password'] + """';
 
466
$dbport = '""" + str(db_port) + """';
 
467
$dbname = '""" + db_forumdbname + """';
 
468
$dbuser = '""" + db_user + """';
 
469
$dbpasswd = '""" + db_password + """';
420
470
 
421
471
$table_prefix = 'phpbb_';
422
472
$acm_type = 'file';
428
478
$forum_secret = '""" + forum_secret +"""';
429
479
?>"""   )
430
480
    
431
 
    conf.close()
 
481
        conf.close()
 
482
    except IOError, (errno, strerror):
 
483
        print "IO error(%s): %s" % (errno, strerror)
 
484
        sys.exit(1)
432
485
 
433
486
    print "Successfully wrote %s" % phpBBconffile
434
487
 
435
488
    print
436
489
    print "You may modify the configuration at any time by editing"
437
490
    print conffile
 
491
    print jailconffile
438
492
    print conf_hfile
439
493
    print phpBBconffile
440
494
    print
441
495
    
442
496
    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
""")