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

« back to all changes in this revision

Viewing changes to setup.py

  • Committer: dcoles
  • Date: 2008-07-03 04:20:54 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:803
Setup: Modularised setup.py so it is now no longer over 1000 lines. This should 
allow us to get in there and tidy up each module much easier. Also removed 
updatejails since this functionality seems to be duplicated with remakeuser.py 
and remakealluser.py scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
# Copy trampoline/trampoline to $target/bin.
56
56
# chown and chmod the installed trampoline.
57
57
# Copy www/ to $target.
58
 
# Copy jail/ to jails template directory (unless --nojail specified).
 
58
# Copy jail/ to jails __staging__ directory (unless --nojail specified).
59
59
 
60
60
import os
61
61
import stat
67
67
import mimetypes
68
68
import compileall
69
69
import getopt
 
70
import hashlib
 
71
import uuid
 
72
import pysvn
70
73
 
71
74
# Import modules from the website is tricky since they're in the www
72
75
# directory.
79
82
# Just get the first 3 characters of sys.version.
80
83
PYTHON_VERSION = sys.version[0:3]
81
84
 
82
 
# Operating system files to copy over into the jail.
83
 
# These will be copied from the given place on the OS file system into the
84
 
# same place within the jail.
85
 
JAIL_FILES = [
86
 
    '/lib/ld-linux.so.2',
87
 
    '/lib/tls/i686/cmov/libc.so.6',
88
 
    '/lib/tls/i686/cmov/libdl.so.2',
89
 
    '/lib/tls/i686/cmov/libm.so.6',
90
 
    '/lib/tls/i686/cmov/libpthread.so.0',
91
 
    '/lib/tls/i686/cmov/libutil.so.1',
92
 
    '/etc/ld.so.conf',
93
 
    '/etc/ld.so.cache',
94
 
    # These 2 files do not exist in Ubuntu
95
 
    #'/etc/ld.so.preload',
96
 
    #'/etc/ld.so.nohwcap',
97
 
    # UNIX commands
98
 
    '/usr/bin/strace',
99
 
    '/bin/ls',
100
 
    '/bin/echo',
101
 
    # Needed by python
102
 
    '/usr/bin/python%s' % PYTHON_VERSION,
103
 
    # Needed by fileservice
104
 
    '/lib/libcom_err.so.2',
105
 
    '/lib/libcrypt.so.1',
106
 
    '/lib/libkeyutils.so.1',
107
 
    '/lib/libresolv.so.2',
108
 
    '/lib/librt.so.1',
109
 
    '/lib/libuuid.so.1',
110
 
    '/usr/lib/libapr-1.so.0',
111
 
    '/usr/lib/libaprutil-1.so.0',
112
 
    '/usr/lib/libdb-4.4.so',
113
 
    '/usr/lib/libexpat.so.1',
114
 
    '/usr/lib/libgcrypt.so.11',
115
 
    '/usr/lib/libgnutls.so.13',
116
 
    '/usr/lib/libgpg-error.so.0',
117
 
    '/usr/lib/libgssapi_krb5.so.2',
118
 
    '/usr/lib/libk5crypto.so.3',
119
 
    '/usr/lib/libkrb5.so.3',
120
 
    '/usr/lib/libkrb5support.so.0',
121
 
    '/usr/lib/liblber.so.2',
122
 
    '/usr/lib/libldap_r.so.2',
123
 
    '/usr/lib/libneon.so.26',
124
 
    '/usr/lib/libpq.so.5',
125
 
    '/usr/lib/libsasl2.so.2',
126
 
    '/usr/lib/libsqlite3.so.0',
127
 
    '/usr/lib/libsvn_client-1.so.1',
128
 
    '/usr/lib/libsvn_delta-1.so.1',
129
 
    '/usr/lib/libsvn_diff-1.so.1',
130
 
    '/usr/lib/libsvn_fs-1.so.1',
131
 
    '/usr/lib/libsvn_fs_base-1.so.1',
132
 
    '/usr/lib/libsvn_fs_fs-1.so.1',
133
 
    '/usr/lib/libsvn_ra-1.so.1',
134
 
    '/usr/lib/libsvn_ra_dav-1.so.1',
135
 
    '/usr/lib/libsvn_ra_local-1.so.1',
136
 
    '/usr/lib/libsvn_ra_svn-1.so.1',
137
 
    '/usr/lib/libsvn_repos-1.so.1',
138
 
    '/usr/lib/libsvn_subr-1.so.1',
139
 
    '/usr/lib/libsvn_wc-1.so.1',
140
 
    '/usr/lib/libtasn1.so.3',
141
 
    '/usr/lib/libxml2.so.2',
142
 
    # Needed by matplotlib
143
 
    '/usr/lib/i686/cmov/libssl.so.0.9.8',
144
 
    '/usr/lib/i686/cmov/libcrypto.so.0.9.8',
145
 
    '/lib/tls/i686/cmov/libnsl.so.1',
146
 
    '/usr/lib/libz.so.1',
147
 
    '/usr/lib/atlas/liblapack.so.3',
148
 
    '/usr/lib/atlas/libblas.so.3',
149
 
    '/usr/lib/libg2c.so.0',
150
 
    '/usr/lib/libstdc++.so.6',
151
 
    '/usr/lib/libfreetype.so.6',
152
 
    '/usr/lib/libpng12.so.0',
153
 
    '/usr/lib/libBLT.2.4.so.8.4',
154
 
    '/usr/lib/libtk8.4.so.0',
155
 
    '/usr/lib/libtcl8.4.so.0',
156
 
    '/usr/lib/tcl8.4/init.tcl',
157
 
    '/usr/lib/libX11.so.6',
158
 
    '/usr/lib/libXau.so.6',
159
 
    '/usr/lib/libXdmcp.so.6',
160
 
    '/lib/libgcc_s.so.1',
161
 
    '/etc/matplotlibrc',
162
 
]
163
 
# Symlinks to make within the jail. Src mapped to dst.
164
 
JAIL_LINKS = {
165
 
    'python%s' % PYTHON_VERSION: 'jail/usr/bin/python',
166
 
}
167
 
# Trees to copy. Src mapped to dst (these will be passed to action_copytree).
168
 
JAIL_COPYTREES = {
169
 
    '/usr/lib/python%s' % PYTHON_VERSION:
170
 
        'jail/usr/lib/python%s' % PYTHON_VERSION,
171
 
    '/usr/share/matplotlib': 'jail/usr/share/matplotlib',
172
 
    '/etc/ld.so.conf.d': 'jail/etc/ld.so.conf.d',
173
 
}
174
 
 
175
85
class ConfigOption:
176
86
    """A configuration option; one of the things written to conf.py."""
177
87
    def __init__(self, option_name, default, prompt, comment):
191
101
 
192
102
# Configuration options, defaults and descriptions
193
103
config_options = []
194
 
config_options.append(ConfigOption("root_dir", "/ivle",
 
104
config_options.append(ConfigOption("root_dir", "/",
195
105
    """Root directory where IVLE is located (in URL space):""",
196
106
    """
197
107
# In URL space, where in the site is IVLE located. (All URLs will be prefixed
204
114
# In the local file system, where IVLE is actually installed.
205
115
# This directory should contain the "www" and "bin" directories."""))
206
116
config_options.append(ConfigOption("jail_base", "/home/informatics/jails",
207
 
    """Root directory where the jails (containing user files) are stored
 
117
    """Location of Directories
 
118
=======================
 
119
Root directory where the jails (containing user files) are stored
208
120
(on the local file system):""",
209
121
    """
210
122
# In the local file system, where are the student/user file spaces located.
218
130
# In the local file system, where are the per-subject file spaces located.
219
131
# The individual subject directories are expected to be located immediately
220
132
# in subdirectories of this location."""))
221
 
config_options.append(ConfigOption("problems_base",
222
 
    "/home/informatics/problems",
223
 
    """Root directory where the problem directories (containing
224
 
subject-independent problem sheets) are stored (on the local file
 
133
config_options.append(ConfigOption("exercises_base",
 
134
    "/home/informatics/exercises",
 
135
    """Root directory where the exercise directories (containing
 
136
subject-independent exercise sheets) are stored (on the local file
225
137
system):""",
226
138
    """
227
 
# In the local file system, where are the subject-independent problem sheet
 
139
# In the local file system, where are the subject-independent exercise sheet
228
140
# file spaces located."""))
 
141
config_options.append(ConfigOption("tos_path",
 
142
    "/home/informatics/tos.html",
 
143
    """Location where the Terms of Service document is stored (on the local
 
144
    file system):""",
 
145
    """
 
146
# In the local file system, where is the Terms of Service document located."""))
 
147
config_options.append(ConfigOption("motd_path",
 
148
    "/home/informatics/motd.html",
 
149
    """Location where the Message of the Day document is stored (on the local
 
150
    file system):""",
 
151
    """
 
152
# In the local file system, where is the Message of the Day document
 
153
# located. This is an HTML file (just the body fragment), which will
 
154
# be displayed on the login page. It is optional."""))
229
155
config_options.append(ConfigOption("public_host", "public.localhost",
230
156
    """Hostname which will cause the server to go into "public mode",
231
157
providing login-free access to student's published work:""",
261
187
    """Database name:""",
262
188
    """
263
189
# Database name"""))
 
190
config_options.append(ConfigOption("db_forumdbname", "ivle_forum",
 
191
    """Forum Database name:""",
 
192
    """
 
193
# Forum Database name"""))
264
194
config_options.append(ConfigOption("db_user", "postgres",
265
195
    """Username for DB server login:""",
266
196
    """
270
200
    (Caution: This password is stored in plaintext in lib/conf/conf.py)""",
271
201
    """
272
202
# Database password"""))
 
203
config_options.append(ConfigOption("auth_modules", "ldap_auth",
 
204
    """Authentication config
 
205
=====================
 
206
Comma-separated list of authentication modules. Only "ldap" is available
 
207
by default.""",
 
208
    """
 
209
# Comma-separated list of authentication modules.
 
210
# These refer to importable Python modules in the www/auth directory.
 
211
# Modules "ldap" and "guest" are available in the source tree, but
 
212
# other modules may be plugged in to auth against organisation-specific
 
213
# auth backends."""))
 
214
config_options.append(ConfigOption("ldap_url", "ldaps://www.example.com",
 
215
    """(LDAP options are only relevant if "ldap" is included in the list of
 
216
auth modules).
 
217
URL for LDAP authentication server:""",
 
218
    """
 
219
# URL for LDAP authentication server"""))
 
220
config_options.append(ConfigOption("ldap_format_string",
 
221
    "uid=%s,ou=users,o=example",
 
222
    """Format string for LDAP auth request:
 
223
    (Must contain a single "%s" for the user's login name)""",
 
224
    """
 
225
# Format string for LDAP auth request
 
226
# (Must contain a single "%s" for the user's login name)"""))
 
227
config_options.append(ConfigOption("svn_addr", "http://svn.localhost/",
 
228
    """Subversion config
 
229
=================
 
230
The base url for accessing subversion repositories:""",
 
231
    """
 
232
# The base url for accessing subversion repositories."""))
 
233
config_options.append(ConfigOption("svn_conf", "/opt/ivle/svn/svn.conf",
 
234
    """The location of the subversion configuration file used by apache
 
235
to host the user repositories:""",
 
236
    """
 
237
# The location of the subversion configuration file used by
 
238
# apache to host the user repositories."""))
 
239
config_options.append(ConfigOption("svn_repo_path", "/home/informatics/repositories",
 
240
    """The root directory for the subversion repositories:""",
 
241
    """
 
242
# The root directory for the subversion repositories."""))
 
243
config_options.append(ConfigOption("svn_auth_ivle", "/opt/ivle/svn/ivle.auth",
 
244
    """The location of the password file used to authenticate users
 
245
of the subversion repository from the ivle server:""",
 
246
    """
 
247
# The location of the password file used to authenticate users
 
248
# of the subversion repository from the ivle server."""))
 
249
config_options.append(ConfigOption("svn_auth_local", "/opt/ivle/svn/local.auth",
 
250
    """The location of the password file used to authenticate local users
 
251
of the subversion repository:""",
 
252
    """
 
253
# The location of the password file used to authenticate local users
 
254
# of the subversion repository."""))
 
255
config_options.append(ConfigOption("usrmgt_host", "localhost",
 
256
    """User Management Server config
 
257
============================
 
258
The hostname where the usrmgt-server runs:""",
 
259
    """
 
260
# The hostname where the usrmgt-server runs."""))
 
261
config_options.append(ConfigOption("usrmgt_port", "2178",
 
262
    """The port where the usrmgt-server runs:""",
 
263
    """
 
264
# The port where the usrmgt-server runs."""))
 
265
config_options.append(ConfigOption("usrmgt_magic", "",
 
266
    """The password for the usrmgt-server:""",
 
267
    """
 
268
# The password for the usrmgt-server."""))
273
269
 
274
270
# Try importing existing conf, but if we can't just set up defaults
275
271
# The reason for this is that these settings are used by other phases
300
296
# as necessary, and include it in the distribution.
301
297
listmake_mimetypes = ['text/x-python', 'text/html',
302
298
    'application/x-javascript', 'application/javascript',
303
 
    'text/css', 'image/png', 'application/xml']
 
299
    'text/css', 'image/png', 'image/gif', 'application/xml']
304
300
 
305
301
# Main function skeleton from Guido van Rossum
306
302
# http://www.artima.com/weblogs/viewpost.jsp?thread=4829
329
325
        return 1
330
326
 
331
327
    # Disallow run as root unless installing
332
 
    if (operation != 'install' and operation != 'updatejails'
 
328
    if (operation != 'install' and operation != 'updatejails' and operation != 
 
329
    'build'
333
330
        and os.geteuid() == 0):
334
331
        print >>sys.stderr, "I do not want to run this stage as root."
335
332
        print >>sys.stderr, "Please run as a normal user."
420
417
Copy trampoline/trampoline to $target/bin.
421
418
chown and chmod the installed trampoline.
422
419
Copy www/ to $target.
423
 
Copy jail/ to jails template directory (unless --nojail specified).
 
420
Copy jail/ to jails __staging__ directory (unless --nojail specified).
424
421
Copy subjects/ to subjects directory (unless --nosubjects specified).
425
422
 
426
423
--nojail        Do not copy the jail.
427
 
--nosubjects    Do not copy the subjects and problems directories.
 
424
--nosubjects    Do not copy the subjects and exercises directories.
428
425
--dry | -n  Print out the actions but don't do anything."""
429
426
    elif operation == 'updatejails':
430
427
        print """sudo python setup.py updatejails [--dry|-n]
442
439
    # We build two separate lists, by walking www and console
443
440
    list_www = build_list_py_files('www')
444
441
    list_lib = build_list_py_files('lib')
445
 
    list_scripts = build_list_py_files('scripts')
446
442
    list_subjects = build_list_py_files('subjects', no_top_level=True)
447
 
    list_problems = build_list_py_files('problems', no_top_level=True)
 
443
    list_exercises = build_list_py_files('exercises', no_top_level=True)
 
444
    list_scripts = [
 
445
        "scripts/python-console",
 
446
        "scripts/fileservice",
 
447
        "scripts/serveservice",
 
448
        "scripts/usrmgt-server",
 
449
        "scripts/diffservice",
 
450
    ]
448
451
    # Make sure that the files generated by conf are in the list
449
452
    # (since listmake is typically run before conf)
450
453
    if "lib/conf/conf.py" not in list_lib:
451
454
        list_lib.append("lib/conf/conf.py")
452
 
    # Make sure that console/python-console is in the list
453
 
    if "scripts/python-console" not in list_scripts:
454
 
        list_scripts.append("scripts/python-console")
455
 
    if "scripts/fileservice" not in list_scripts:
456
 
        list_scripts.append("scripts/fileservice")
457
455
    # Write these out to a file
458
456
    cwd = os.getcwd()
459
457
    # the files that will be created/overwritten
486
484
list_subjects = """)
487
485
        writelist_pretty(file, list_subjects)
488
486
        file.write("""
489
 
# List of all installable files in problems directory.
 
487
# List of all installable files in exercises directory.
490
488
# This is to install sample exercise material.
491
 
list_problems = """)
492
 
        writelist_pretty(file, list_problems)
 
489
list_exercises = """)
 
490
        writelist_pretty(file, list_exercises)
493
491
 
494
492
        file.close()
495
493
    except IOError, (errno, strerror):
535
533
        file.write(']\n')
536
534
 
537
535
def conf(args):
538
 
    global db_port
 
536
    global db_port, usrmgt_port
539
537
    # Set up some variables
540
538
 
541
539
    cwd = os.getcwd()
543
541
    conffile = os.path.join(cwd, "lib/conf/conf.py")
544
542
    jailconffile = os.path.join(cwd, "lib/conf/jailconf.py")
545
543
    conf_hfile = os.path.join(cwd, "trampoline/conf.h")
 
544
    phpBBconffile = os.path.join(cwd, "www/php/phpBB3/config.php")
 
545
    usrmgtserver_initdfile = os.path.join(cwd, "doc/setup/usrmgt-server.init")
546
546
 
547
547
    # Get command-line arguments to avoid asking questions.
548
548
 
562
562
    %s
563
563
    %s
564
564
    %s
 
565
    %s
 
566
    %s
565
567
prompting you for details about your configuration. The file will be
566
568
overwritten if it already exists. It will *not* install or deploy IVLE.
567
569
 
568
570
Please hit Ctrl+C now if you do not wish to do this.
569
 
""" % (conffile, jailconffile, conf_hfile)
 
571
""" % (conffile, jailconffile, conf_hfile, phpBBconffile, usrmgtserver_initdfile)
570
572
 
571
573
        # Get information from the administrator
572
574
        # If EOF is encountered at any time during the questioning, just exit
598
600
        "Invalid DB port (%s).\n"
599
601
        "Must be an integer between 0 and 65535." % repr(db_port))
600
602
        return 1
 
603
    try:
 
604
        usrmgt_port = int(usrmgt_port)
 
605
        if usrmgt_port < 0 or usrmgt_port >= 65536: raise ValueError()
 
606
    except ValueError:
 
607
        print >>sys.stderr, (
 
608
        "Invalid user management port (%s).\n"
 
609
        "Must be an integer between 0 and 65535." % repr(usrmgt_port))
 
610
        return 1
 
611
 
 
612
    # Generate the forum secret
 
613
    forum_secret = hashlib.md5(uuid.uuid4().bytes).hexdigest()
601
614
 
602
615
    # Write lib/conf/conf.py
603
616
 
613
626
            conf.write('%s\n%s = %s\n' % (opt.comment, opt.option_name,
614
627
                repr(globals()[opt.option_name])))
615
628
 
 
629
        # Add the forum secret to the config file (regenerated each config)
 
630
        conf.write('forum_secret = "%s"\n' % (forum_secret))
 
631
 
616
632
        conf.close()
617
633
    except IOError, (errno, strerror):
618
634
        print "IO error(%s): %s" % (errno, strerror)
692
708
 
693
709
    print "Successfully wrote trampoline/conf.h"
694
710
 
 
711
    # Write www/php/phpBB3/config.php
 
712
 
 
713
    try:
 
714
        conf = open(phpBBconffile, "w")
 
715
        
 
716
        # php-pg work around
 
717
        if db_host == 'localhost':
 
718
            forumdb_host = '127.0.0.1'
 
719
        else:
 
720
            forumdb_host = db_host
 
721
 
 
722
        conf.write( """<?php
 
723
// phpBB 3.0.x auto-generated configuration file
 
724
// Do not change anything in this file!
 
725
$dbms = 'postgres';
 
726
$dbhost = '""" + forumdb_host + """';
 
727
$dbport = '""" + str(db_port) + """';
 
728
$dbname = '""" + db_forumdbname + """';
 
729
$dbuser = '""" + db_user + """';
 
730
$dbpasswd = '""" + db_password + """';
 
731
 
 
732
$table_prefix = 'phpbb_';
 
733
$acm_type = 'file';
 
734
$load_extensions = '';
 
735
@define('PHPBB_INSTALLED', true);
 
736
// @define('DEBUG', true);
 
737
//@define('DEBUG_EXTRA', true);
 
738
 
 
739
$forum_secret = '""" + forum_secret +"""';
 
740
?>"""   )
 
741
    
 
742
        conf.close()
 
743
    except IOError, (errno, strerror):
 
744
        print "IO error(%s): %s" % (errno, strerror)
 
745
        sys.exit(1)
 
746
 
 
747
    print "Successfully wrote www/php/phpBB3/config.php"
 
748
 
 
749
    # Write lib/conf/usrmgt-server.init
 
750
 
 
751
    try:
 
752
        conf = open(usrmgtserver_initdfile, "w")
 
753
 
 
754
        conf.write( '''#! /bin/sh
 
755
 
 
756
# Works for Ubuntu. Check before using on other distributions
 
757
 
 
758
### BEGIN INIT INFO
 
759
# Provides:          usrmgt-server
 
760
# Required-Start:    $syslog $networking $urandom
 
761
# Required-Stop:     $syslog
 
762
# Default-Start:     2 3 4 5
 
763
# Default-Stop:      1
 
764
# Short-Description: IVLE user management server
 
765
# Description:       Daemon connecting to the IVLE user management database.
 
766
### END INIT INFO
 
767
 
 
768
PATH=/sbin:/bin:/usr/sbin:/usr/bin
 
769
DESC="IVLE user management server"
 
770
NAME=usrmgt-server
 
771
DAEMON=/opt/ivle/scripts/$NAME
 
772
DAEMON_ARGS="''' + str(usrmgt_port) + ''' ''' + usrmgt_magic + '''"
 
773
PIDFILE=/var/run/$NAME.pid
 
774
SCRIPTNAME=/etc/init.d/usrmgt-server
 
775
 
 
776
# Exit if the daemon does not exist 
 
777
test -f $DAEMON || exit 0
 
778
 
 
779
# Load the VERBOSE setting and other rcS variables
 
780
[ -f /etc/default/rcS ] && . /etc/default/rcS
 
781
 
 
782
# Define LSB log_* functions.
 
783
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
 
784
. /lib/lsb/init-functions
 
785
 
 
786
#
 
787
# Function that starts the daemon/service
 
788
#
 
789
do_start()
 
790
{
 
791
        # Return
 
792
        #   0 if daemon has been started
 
793
        #   1 if daemon was already running
 
794
        #   2 if daemon could not be started
 
795
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
 
796
                || return 1
 
797
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
 
798
                $DAEMON_ARGS \
 
799
                || return 2
 
800
        # Add code here, if necessary, that waits for the process to be ready
 
801
        # to handle requests from services started subsequently which depend
 
802
        # on this one.  As a last resort, sleep for some time.
 
803
}
 
804
 
 
805
#
 
806
# Function that stops the daemon/service
 
807
#
 
808
do_stop()
 
809
{
 
810
        # Return
 
811
        #   0 if daemon has been stopped
 
812
        #   1 if daemon was already stopped
 
813
        #   2 if daemon could not be stopped
 
814
        #   other if a failure occurred
 
815
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
 
816
        RETVAL="$?"
 
817
        [ "$RETVAL" = 2 ] && return 2
 
818
        # Wait for children to finish too if this is a daemon that forks
 
819
        # and if the daemon is only ever run from this initscript.
 
820
        # If the above conditions are not satisfied then add some other code
 
821
        # that waits for the process to drop all resources that could be
 
822
        # needed by services started subsequently.  A last resort is to
 
823
        # sleep for some time.
 
824
        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
 
825
        [ "$?" = 2 ] && return 2
 
826
        # Many daemons don't delete their pidfiles when they exit.
 
827
        rm -f $PIDFILE
 
828
        return "$RETVAL"
 
829
}
 
830
 
 
831
#
 
832
# Function that sends a SIGHUP to the daemon/service
 
833
#
 
834
do_reload() {
 
835
        #
 
836
        # If the daemon can reload its configuration without
 
837
        # restarting (for example, when it is sent a SIGHUP),
 
838
        # then implement that here.
 
839
        #
 
840
        start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
 
841
        return 0
 
842
}
 
843
 
 
844
case "$1" in
 
845
  start)
 
846
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
 
847
        do_start
 
848
        case "$?" in
 
849
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 
850
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 
851
        esac
 
852
        ;;
 
853
  stop)
 
854
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
 
855
        do_stop
 
856
        case "$?" in
 
857
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 
858
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 
859
        esac
 
860
        ;;
 
861
  #reload|force-reload)
 
862
        #
 
863
        # If do_reload() is not implemented then leave this commented out
 
864
        # and leave 'force-reload' as an alias for 'restart'.
 
865
        #
 
866
        #log_daemon_msg "Reloading $DESC" "$NAME"
 
867
        #do_reload
 
868
        #log_end_msg $?
 
869
        #;;
 
870
  restart|force-reload)
 
871
        #
 
872
        # If the "reload" option is implemented then remove the
 
873
        # 'force-reload' alias
 
874
        #
 
875
        log_daemon_msg "Restarting $DESC" "$NAME"
 
876
        do_stop
 
877
        case "$?" in
 
878
          0|1)
 
879
                do_start
 
880
                case "$?" in
 
881
                        0) log_end_msg 0 ;;
 
882
                        1) log_end_msg 1 ;; # Old process is still running
 
883
                        *) log_end_msg 1 ;; # Failed to start
 
884
                esac
 
885
                ;;
 
886
          *)
 
887
                # Failed to stop
 
888
                log_end_msg 1
 
889
                ;;
 
890
        esac
 
891
        ;;
 
892
  *)
 
893
        #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
 
894
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
 
895
        exit 3
 
896
        ;;
 
897
esac
 
898
 
 
899
:
 
900
''')
 
901
        
 
902
        conf.close()
 
903
    except IOError, (errno, strerror):
 
904
        print "IO error(%s): %s" % (errno, strerror)
 
905
        sys.exit(1)
 
906
 
 
907
    # fix permissions as the file contains the database password
 
908
    try:
 
909
        os.chmod('doc/setup/usrmgt-server.init', 0600)
 
910
    except OSError, (errno, strerror):
 
911
        print "WARNING: Couldn't chmod doc/setup/usrmgt-server.init:"
 
912
        print "OS error(%s): %s" % (errno, strerror)
 
913
 
 
914
    print "Successfully wrote lib/conf/usrmgt-server.init"
 
915
 
695
916
    print
696
917
    print "You may modify the configuration at any time by editing"
697
918
    print conffile
698
919
    print jailconffile
699
920
    print conf_hfile
 
921
    print phpBBconffile
 
922
    print usrmgtserver_initdfile
700
923
    print
701
924
    return 0
702
925
 
708
931
 
709
932
    if dry:
710
933
        print "Dry run (no actions will be executed\n"
 
934
    
 
935
    if not dry and os.geteuid() != 0:
 
936
        print >>sys.stderr, "Must be root to run build"
 
937
        print >>sys.stderr, "(I need to chroot)."
 
938
        return 1
 
939
    
 
940
    # Find out the revison number
 
941
    revnum = get_svn_revision()
 
942
    print "Building Revision %s"%str(revnum)
 
943
    if not dry:
 
944
        vfile = open('BUILD-VERSION','w')
 
945
        vfile.write(str(revnum) + '\n')
 
946
        vfile.close()
711
947
 
712
948
    # Compile the trampoline
713
949
    curdir = os.getcwd()
717
953
 
718
954
    # Create the jail and its subdirectories
719
955
    # Note: Other subdirs will be made by copying files
720
 
    action_mkdir('jail', dry)
721
 
    action_mkdir('jail/home', dry)
722
 
    action_mkdir('jail/tmp', dry)
 
956
    action_runprog('./buildjail.sh', [], dry)
723
957
 
724
958
    # Copy all console and operating system files into the jail
725
959
    action_copylist(install_list.list_scripts, 'jail/opt/ivle', dry)
726
 
    copy_os_files_jail(dry)
727
960
    # Chmod the python console
728
961
    action_chmod_x('jail/opt/ivle/scripts/python-console', dry)
729
962
    action_chmod_x('jail/opt/ivle/scripts/fileservice', dry)
 
963
    action_chmod_x('jail/opt/ivle/scripts/serveservice', dry)
730
964
    
731
965
    # Also copy the IVLE lib directory into the jail
732
966
    # This is necessary for running certain scripts
755
989
 
756
990
    return 0
757
991
 
758
 
def copy_os_files_jail(dry):
759
 
    """Copies necessary Operating System files from their usual locations
760
 
    into the jail/ directory of the cwd."""
761
 
    # Currently source paths are configured for Ubuntu.
762
 
    for filename in JAIL_FILES:
763
 
        copy_file_to_jail(filename, dry)
764
 
    for src, dst in JAIL_LINKS.items():
765
 
        action_symlink(src, dst, dry)
766
 
    for src, dst in JAIL_COPYTREES.items():
767
 
        action_copytree(src, dst, dry)
768
 
 
769
992
def copy_file_to_jail(src, dry):
770
993
    """Copies a single file from an absolute location into the same location
771
994
    within the jail. src must begin with a '/'. The jail will be located
799
1022
    # chown trampoline to root and set setuid bit
800
1023
    action_chown_setuid(tramppath, dry)
801
1024
 
 
1025
    # Create a scripts directory to put the usrmgt-server in.
 
1026
    action_mkdir(os.path.join(ivle_install_dir, 'scripts'), dry)
 
1027
    usrmgtpath = os.path.join(ivle_install_dir, 'scripts/usrmgt-server')
 
1028
    action_copyfile('scripts/usrmgt-server', usrmgtpath, dry)
 
1029
    action_chmod_x(usrmgtpath, dry)
 
1030
 
802
1031
    # Copy the www and lib directories using the list
803
1032
    action_copylist(install_list.list_www, ivle_install_dir, dry)
804
1033
    action_copylist(install_list.list_lib, ivle_install_dir, dry)
 
1034
    
 
1035
    # Copy the php directory
 
1036
    forum_dir = "www/php/phpBB3"
 
1037
    forum_path = os.path.join(ivle_install_dir, forum_dir)
 
1038
    action_copytree(forum_dir, forum_path, dry)
 
1039
    print "chown -R www-data:www-data %s" % forum_path
 
1040
    if not dry:
 
1041
        os.system("chown -R www-data:www-data %s" % forum_path)
805
1042
 
806
1043
    if not nojail:
807
1044
        # Copy the local jail directory built by the build action
808
 
        # to the jails template directory (it will be used as a template
809
 
        # for all the students' jails).
810
 
        action_copytree('jail', os.path.join(jail_base, 'template'), dry)
 
1045
        # to the jails __staging__ directory (it will be used to help build
 
1046
        # all the students' jails).
 
1047
        action_copytree('jail', os.path.join(jail_base, '__staging__'), dry)
811
1048
    if not nosubjects:
812
 
        # Copy the subjects and problems directories across
 
1049
        # Copy the subjects and exercises directories across
813
1050
        action_copylist(install_list.list_subjects, subjects_base, dry,
814
1051
            srcdir="./subjects")
815
 
        action_copylist(install_list.list_problems, problems_base, dry,
816
 
            srcdir="./problems")
 
1052
        action_copylist(install_list.list_exercises, exercises_base, dry,
 
1053
            srcdir="./exercises")
817
1054
 
818
1055
    # Append IVLE path to ivle.pth in python site packages
819
1056
    # (Unless it's already there)
838
1075
    if write_ivle_lib_pth:
839
1076
        action_append(ivle_pth, ivle_lib)
840
1077
 
 
1078
 
 
1079
    # Create the ivle working revision record file
 
1080
    action_mkdir(os.path.join(ivle_install_dir, 'version'), dry)
 
1081
    ivle_revision_record_file = os.path.join(ivle_install_dir, 'version/ivle-revision.txt')
 
1082
    if not dry:
 
1083
        try:
 
1084
            conf = open(ivle_revision_record_file, "w")
 
1085
 
 
1086
            conf.write( "# IVLE code revision listing generated by running 'svn status -v ..' from " + os.getcwd() + "\n#\n\n")
 
1087
 
 
1088
            conf.close()
 
1089
        except IOError, (errno, strerror):
 
1090
            print "IO error(%s): %s" % (errno, strerror)
 
1091
            sys.exit(1)
 
1092
 
 
1093
        os.system("svn status -v .. >> %s" % ivle_revision_record_file)
 
1094
 
 
1095
    print "Wrote IVLE code revision status to %s" % ivle_revision_record_file
 
1096
 
841
1097
    return 0
842
1098
 
843
1099
def updatejails(args):
854
1110
        print >>sys.stderr, "(I need to chown some files)."
855
1111
        return 1
856
1112
 
857
 
    # Update the template jail directory in case it hasn't been installed
 
1113
    # Update the staging jail directory in case it hasn't been installed
858
1114
    # recently.
859
 
    action_copytree('jail', os.path.join(jail_base, 'template'), dry)
 
1115
    action_copytree('jail', os.path.join(jail_base, '__staging__'), dry)
860
1116
 
861
1117
    # Re-link all the files in all students jails.
862
1118
    for dir in os.listdir(jail_base):
863
 
        if dir == 'template': continue
 
1119
        if dir == '__staging__': continue
864
1120
        # First back up the student's home directory
865
1121
        temp_home = os.tmpnam()
866
1122
        action_rename(os.path.join(jail_base, dir, 'home'), temp_home, dry)
867
1123
        # Delete the student's jail and relink the jail files
868
 
        action_linktree(os.path.join(jail_base, 'template'),
 
1124
        action_linktree(os.path.join(jail_base, '__staging__'),
869
1125
            os.path.join(jail_base, dir), dry)
870
1126
        # Restore the student's home directory
871
1127
        action_rename(temp_home, os.path.join(jail_base, dir, 'home'), dry)
943
1199
    directories as necessary.
944
1200
 
945
1201
    See shutil.copytree."""
 
1202
    # Allow copying over itself
 
1203
    if (os.path.normpath(os.path.join(os.getcwd(),src)) ==
 
1204
        os.path.normpath(os.path.join(os.getcwd(),dst))):
 
1205
        return
946
1206
    action_remove(dst, dry)
947
1207
    print "cp -r", src, dst
948
1208
    if dry: return
1065
1325
            del list[i]
1066
1326
        i -= 1
1067
1327
 
 
1328
def get_svn_revision():
 
1329
    """Returns either the current SVN revision of this build, or None"""
 
1330
    try:
 
1331
        svn = pysvn.Client()
 
1332
        entry = svn.info('.')
 
1333
        revnum = entry.revision.number
 
1334
    except pysvn.ClientError, e:
 
1335
        revnum = None
 
1336
    return revnum
 
1337
 
1068
1338
if __name__ == "__main__":
1069
1339
    sys.exit(main())
 
1340