79
82
# Just get the first 3 characters of sys.version.
80
83
PYTHON_VERSION = sys.version[0:3]
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.
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',
94
# These 2 files do not exist in Ubuntu
95
#'/etc/ld.so.preload',
96
#'/etc/ld.so.nohwcap',
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',
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',
163
# Symlinks to make within the jail. Src mapped to dst.
165
'python%s' % PYTHON_VERSION: 'jail/usr/bin/python',
167
# Trees to copy. Src mapped to dst (these will be passed to action_copytree).
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',
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):
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
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
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
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:""",
270
200
(Caution: This password is stored in plaintext in lib/conf/conf.py)""",
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
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
217
URL for LDAP authentication server:""",
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)""",
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/",
230
The base url for accessing subversion repositories:""",
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:""",
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:""",
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:""",
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:""",
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:""",
260
# The hostname where the usrmgt-server runs."""))
261
config_options.append(ConfigOption("usrmgt_port", "2178",
262
"""The port where the usrmgt-server runs:""",
264
# The port where the usrmgt-server runs."""))
265
config_options.append(ConfigOption("usrmgt_magic", "",
266
"""The password for the usrmgt-server:""",
268
# The password for the usrmgt-server."""))
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
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)
445
"scripts/python-console",
446
"scripts/fileservice",
447
"scripts/serveservice",
448
"scripts/usrmgt-server",
449
"scripts/diffservice",
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
693
709
print "Successfully wrote trampoline/conf.h"
711
# Write www/php/phpBB3/config.php
714
conf = open(phpBBconffile, "w")
717
if db_host == 'localhost':
718
forumdb_host = '127.0.0.1'
720
forumdb_host = db_host
723
// phpBB 3.0.x auto-generated configuration file
724
// Do not change anything in this file!
726
$dbhost = '""" + forumdb_host + """';
727
$dbport = '""" + str(db_port) + """';
728
$dbname = '""" + db_forumdbname + """';
729
$dbuser = '""" + db_user + """';
730
$dbpasswd = '""" + db_password + """';
732
$table_prefix = 'phpbb_';
734
$load_extensions = '';
735
@define('PHPBB_INSTALLED', true);
736
// @define('DEBUG', true);
737
//@define('DEBUG_EXTRA', true);
739
$forum_secret = '""" + forum_secret +"""';
743
except IOError, (errno, strerror):
744
print "IO error(%s): %s" % (errno, strerror)
747
print "Successfully wrote www/php/phpBB3/config.php"
749
# Write lib/conf/usrmgt-server.init
752
conf = open(usrmgtserver_initdfile, "w")
754
conf.write( '''#! /bin/sh
756
# Works for Ubuntu. Check before using on other distributions
759
# Provides: usrmgt-server
760
# Required-Start: $syslog $networking $urandom
761
# Required-Stop: $syslog
762
# Default-Start: 2 3 4 5
764
# Short-Description: IVLE user management server
765
# Description: Daemon connecting to the IVLE user management database.
768
PATH=/sbin:/bin:/usr/sbin:/usr/bin
769
DESC="IVLE user management 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
776
# Exit if the daemon does not exist
777
test -f $DAEMON || exit 0
779
# Load the VERBOSE setting and other rcS variables
780
[ -f /etc/default/rcS ] && . /etc/default/rcS
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
787
# Function that starts the daemon/service
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 \
797
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
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.
806
# Function that stops the daemon/service
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
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.
832
# Function that sends a SIGHUP to the daemon/service
836
# If the daemon can reload its configuration without
837
# restarting (for example, when it is sent a SIGHUP),
838
# then implement that here.
840
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
846
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
849
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
850
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
854
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
857
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
858
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
861
#reload|force-reload)
863
# If do_reload() is not implemented then leave this commented out
864
# and leave 'force-reload' as an alias for 'restart'.
866
#log_daemon_msg "Reloading $DESC" "$NAME"
870
restart|force-reload)
872
# If the "reload" option is implemented then remove the
873
# 'force-reload' alias
875
log_daemon_msg "Restarting $DESC" "$NAME"
882
1) log_end_msg 1 ;; # Old process is still running
883
*) log_end_msg 1 ;; # Failed to start
893
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
894
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
903
except IOError, (errno, strerror):
904
print "IO error(%s): %s" % (errno, strerror)
907
# fix permissions as the file contains the database password
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)
914
print "Successfully wrote lib/conf/usrmgt-server.init"
696
917
print "You may modify the configuration at any time by editing"
698
919
print jailconffile
922
print usrmgtserver_initdfile
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)
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)
731
965
# Also copy the IVLE lib directory into the jail
732
966
# This is necessary for running certain scripts
799
1022
# chown trampoline to root and set setuid bit
800
1023
action_chown_setuid(tramppath, dry)
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)
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)
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
1041
os.system("chown -R www-data:www-data %s" % forum_path)
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,
1052
action_copylist(install_list.list_exercises, exercises_base, dry,
1053
srcdir="./exercises")
818
1055
# Append IVLE path to ivle.pth in python site packages
819
1056
# (Unless it's already there)
854
1110
print >>sys.stderr, "(I need to chown some files)."
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
859
action_copytree('jail', os.path.join(jail_base, 'template'), dry)
1115
action_copytree('jail', os.path.join(jail_base, '__staging__'), dry)
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)