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

« back to all changes in this revision

Viewing changes to setup.py

  • Committer: mattgiuca
  • Date: 2008-02-05 06:29:54 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:418
Renamed trunk/console to trunk/scripts. We are now able to put more scripts in
here such as fileservice.
Added fileservice (empty at the moment).
setup.py, consoleservice: Updated so they refer to scripts now instead of
console directory. (This changes listmake and install_list.py as well).

Added remakeuser.py which lets you recreate a user's jail without creating a
DB entry (but the user is already supposed to exist).

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 __staging__ directory (unless --nojail specified).
 
58
# Copy jail/ to jails template 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
73
70
 
74
71
# Import modules from the website is tricky since they're in the www
75
72
# directory.
103
100
    '/bin/echo',
104
101
    # Needed by python
105
102
    '/usr/bin/python%s' % PYTHON_VERSION,
106
 
    # Needed by fileservice
107
 
    '/lib/libcom_err.so.2',
108
 
    '/lib/libcrypt.so.1',
109
 
    '/lib/libkeyutils.so.1',
110
 
    '/lib/libresolv.so.2',
111
 
    '/lib/librt.so.1',
112
 
    '/lib/libuuid.so.1',
113
 
    '/usr/lib/libapr-1.so.0',
114
 
    '/usr/lib/libaprutil-1.so.0',
115
 
    '/usr/lib/libapt-pkg-libc6.6-6.so.4.5',
116
 
    '/usr/lib/libdb-4.6.so',
117
 
    '/usr/lib/libexpat.so.1',
118
 
    '/usr/lib/libgcrypt.so.11',
119
 
    '/usr/lib/libgnutls.so.13',
120
 
    '/usr/lib/libgpg-error.so.0',
121
 
    '/usr/lib/libgssapi_krb5.so.2',
122
 
    '/usr/lib/libk5crypto.so.3',
123
 
    '/usr/lib/libkrb5.so.3',
124
 
    '/usr/lib/libkrb5support.so.0',
125
 
    '/usr/lib/liblber.so.2',
126
 
    '/usr/lib/liblber-2.4.so.2',
127
 
    '/usr/lib/libldap_r.so.2',
128
 
    '/usr/lib/libldap_r-2.4.so.2',
129
 
    '/usr/lib/libneon.so.27',
130
 
    '/usr/lib/libpq.so.5',
131
 
    '/usr/lib/libsasl2.so.2',
132
 
    '/usr/lib/libsqlite3.so.0',
133
 
    '/usr/lib/libsvn_client-1.so.1',
134
 
    '/usr/lib/libsvn_delta-1.so.1',
135
 
    '/usr/lib/libsvn_diff-1.so.1',
136
 
    '/usr/lib/libsvn_fs-1.so.1',
137
 
    '/usr/lib/libsvn_fs_base-1.so.1',
138
 
    '/usr/lib/libsvn_fs_fs-1.so.1',
139
 
    '/usr/lib/libsvn_ra-1.so.1',
140
 
    '/usr/lib/libsvn_ra_dav-1.so.1',
141
 
    '/usr/lib/libsvn_ra_local-1.so.1',
142
 
    '/usr/lib/libsvn_ra_svn-1.so.1',
143
 
    '/usr/lib/libsvn_repos-1.so.1',
144
 
    '/usr/lib/libsvn_subr-1.so.1',
145
 
    '/usr/lib/libsvn_wc-1.so.1',
146
 
    '/usr/lib/libtasn1.so.3',
147
 
    '/usr/lib/libxml2.so.2',
148
103
    # Needed by matplotlib
149
104
    '/usr/lib/i686/cmov/libssl.so.0.9.8',
150
105
    '/usr/lib/i686/cmov/libcrypto.so.0.9.8',
165
120
    '/usr/lib/libXdmcp.so.6',
166
121
    '/lib/libgcc_s.so.1',
167
122
    '/etc/matplotlibrc',
168
 
    # Needed for resolv
169
 
    '/lib/libnss_dns.so.2',
170
 
    '/lib/libnss_mdns4_minimal.so.2',
171
 
    '/etc/hosts',
172
 
    '/etc/resolv.conf',
173
 
    #'/etc/hosts.conf',
174
 
    #'/etc/hostname',
175
 
    '/etc/nsswitch.conf',
176
 
    '/lib/libnss_files.so.2',
177
 
    # Needed for PIL
178
 
    '/usr/lib/libjpeg.so.62',
179
 
    # Needed by lxml
180
 
    '/usr/lib/libxslt.so.1',
181
 
    '/usr/lib/libexslt.so.0',
182
 
    # Needed by elementtree
183
 
    '/usr/lib/libtidy-0.99.so.0',
184
123
]
185
124
# Symlinks to make within the jail. Src mapped to dst.
186
125
JAIL_LINKS = {
190
129
JAIL_COPYTREES = {
191
130
    '/usr/lib/python%s' % PYTHON_VERSION:
192
131
        'jail/usr/lib/python%s' % PYTHON_VERSION,
193
 
    '/var/lib/python-support/python%s' % PYTHON_VERSION:
194
 
        'jail/var/lib/python-support/python%s' %PYTHON_VERSION,
195
132
    '/usr/share/matplotlib': 'jail/usr/share/matplotlib',
196
133
    '/etc/ld.so.conf.d': 'jail/etc/ld.so.conf.d',
197
 
    '/usr/share/pycentral': 'jail/usr/share/pycentral',
198
 
    '/usr/share/pycentral-data': 'jail/usr/share/pycentral-data',
199
 
    '/usr/share/nltk': 'jail/usr/share/nltk',
200
134
}
201
135
 
202
136
class ConfigOption:
218
152
 
219
153
# Configuration options, defaults and descriptions
220
154
config_options = []
221
 
config_options.append(ConfigOption("root_dir", "/",
 
155
config_options.append(ConfigOption("root_dir", "/ivle",
222
156
    """Root directory where IVLE is located (in URL space):""",
223
157
    """
224
158
# In URL space, where in the site is IVLE located. (All URLs will be prefixed
231
165
# In the local file system, where IVLE is actually installed.
232
166
# This directory should contain the "www" and "bin" directories."""))
233
167
config_options.append(ConfigOption("jail_base", "/home/informatics/jails",
234
 
    """Location of Directories
235
 
=======================
236
 
Root directory where the jails (containing user files) are stored
 
168
    """Root directory where the jails (containing user files) are stored
237
169
(on the local file system):""",
238
170
    """
239
171
# In the local file system, where are the student/user file spaces located.
247
179
# In the local file system, where are the per-subject file spaces located.
248
180
# The individual subject directories are expected to be located immediately
249
181
# in subdirectories of this location."""))
250
 
config_options.append(ConfigOption("exercises_base",
251
 
    "/home/informatics/exercises",
252
 
    """Root directory where the exercise directories (containing
253
 
subject-independent exercise sheets) are stored (on the local file
 
182
config_options.append(ConfigOption("problems_base",
 
183
    "/home/informatics/problems",
 
184
    """Root directory where the problem directories (containing
 
185
subject-independent problem sheets) are stored (on the local file
254
186
system):""",
255
187
    """
256
 
# In the local file system, where are the subject-independent exercise sheet
 
188
# In the local file system, where are the subject-independent problem sheet
257
189
# file spaces located."""))
258
 
config_options.append(ConfigOption("tos_path",
259
 
    "/home/informatics/tos.html",
260
 
    """Location where the Terms of Service document is stored (on the local
261
 
    file system):""",
262
 
    """
263
 
# In the local file system, where is the Terms of Service document located."""))
264
 
config_options.append(ConfigOption("motd_path",
265
 
    "/home/informatics/motd.html",
266
 
    """Location where the Message of the Day document is stored (on the local
267
 
    file system):""",
268
 
    """
269
 
# In the local file system, where is the Message of the Day document
270
 
# located. This is an HTML file (just the body fragment), which will
271
 
# be displayed on the login page. It is optional."""))
272
190
config_options.append(ConfigOption("public_host", "public.localhost",
273
191
    """Hostname which will cause the server to go into "public mode",
274
192
providing login-free access to student's published work:""",
304
222
    """Database name:""",
305
223
    """
306
224
# Database name"""))
307
 
config_options.append(ConfigOption("db_forumdbname", "ivle_forum",
308
 
    """Forum Database name:""",
309
 
    """
310
 
# Forum Database name"""))
311
225
config_options.append(ConfigOption("db_user", "postgres",
312
226
    """Username for DB server login:""",
313
227
    """
317
231
    (Caution: This password is stored in plaintext in lib/conf/conf.py)""",
318
232
    """
319
233
# Database password"""))
320
 
config_options.append(ConfigOption("auth_modules", "ldap_auth",
321
 
    """Authentication config
322
 
=====================
323
 
Comma-separated list of authentication modules. Only "ldap" is available
324
 
by default.""",
325
 
    """
326
 
# Comma-separated list of authentication modules.
327
 
# These refer to importable Python modules in the www/auth directory.
328
 
# Modules "ldap" and "guest" are available in the source tree, but
329
 
# other modules may be plugged in to auth against organisation-specific
330
 
# auth backends."""))
331
 
config_options.append(ConfigOption("ldap_url", "ldaps://www.example.com",
332
 
    """(LDAP options are only relevant if "ldap" is included in the list of
333
 
auth modules).
334
 
URL for LDAP authentication server:""",
335
 
    """
336
 
# URL for LDAP authentication server"""))
337
 
config_options.append(ConfigOption("ldap_format_string",
338
 
    "uid=%s,ou=users,o=example",
339
 
    """Format string for LDAP auth request:
340
 
    (Must contain a single "%s" for the user's login name)""",
341
 
    """
342
 
# Format string for LDAP auth request
343
 
# (Must contain a single "%s" for the user's login name)"""))
344
 
config_options.append(ConfigOption("svn_addr", "http://svn.localhost/",
345
 
    """Subversion config
346
 
=================
347
 
The base url for accessing subversion repositories:""",
348
 
    """
349
 
# The base url for accessing subversion repositories."""))
350
 
config_options.append(ConfigOption("svn_conf", "/opt/ivle/svn/svn.conf",
351
 
    """The location of the subversion configuration file used by apache
352
 
to host the user repositories:""",
353
 
    """
354
 
# The location of the subversion configuration file used by
355
 
# apache to host the user repositories."""))
356
 
config_options.append(ConfigOption("svn_repo_path", "/home/informatics/repositories",
357
 
    """The root directory for the subversion repositories:""",
358
 
    """
359
 
# The root directory for the subversion repositories."""))
360
 
config_options.append(ConfigOption("svn_auth_ivle", "/opt/ivle/svn/ivle.auth",
361
 
    """The location of the password file used to authenticate users
362
 
of the subversion repository from the ivle server:""",
363
 
    """
364
 
# The location of the password file used to authenticate users
365
 
# of the subversion repository from the ivle server."""))
366
 
config_options.append(ConfigOption("svn_auth_local", "/opt/ivle/svn/local.auth",
367
 
    """The location of the password file used to authenticate local users
368
 
of the subversion repository:""",
369
 
    """
370
 
# The location of the password file used to authenticate local users
371
 
# of the subversion repository."""))
372
 
config_options.append(ConfigOption("usrmgt_host", "localhost",
373
 
    """User Management Server config
374
 
============================
375
 
The hostname where the usrmgt-server runs:""",
376
 
    """
377
 
# The hostname where the usrmgt-server runs."""))
378
 
config_options.append(ConfigOption("usrmgt_port", "2178",
379
 
    """The port where the usrmgt-server runs:""",
380
 
    """
381
 
# The port where the usrmgt-server runs."""))
382
 
config_options.append(ConfigOption("usrmgt_magic", "",
383
 
    """The password for the usrmgt-server:""",
384
 
    """
385
 
# The password for the usrmgt-server."""))
386
234
 
387
235
# Try importing existing conf, but if we can't just set up defaults
388
236
# The reason for this is that these settings are used by other phases
413
261
# as necessary, and include it in the distribution.
414
262
listmake_mimetypes = ['text/x-python', 'text/html',
415
263
    'application/x-javascript', 'application/javascript',
416
 
    'text/css', 'image/png', 'image/gif', 'application/xml']
 
264
    'text/css', 'image/png', 'application/xml']
417
265
 
418
266
# Main function skeleton from Guido van Rossum
419
267
# http://www.artima.com/weblogs/viewpost.jsp?thread=4829
533
381
Copy trampoline/trampoline to $target/bin.
534
382
chown and chmod the installed trampoline.
535
383
Copy www/ to $target.
536
 
Copy jail/ to jails __staging__ directory (unless --nojail specified).
 
384
Copy jail/ to jails template directory (unless --nojail specified).
537
385
Copy subjects/ to subjects directory (unless --nosubjects specified).
538
386
 
539
387
--nojail        Do not copy the jail.
540
 
--nosubjects    Do not copy the subjects and exercises directories.
 
388
--nosubjects    Do not copy the subjects and problems directories.
541
389
--dry | -n  Print out the actions but don't do anything."""
542
390
    elif operation == 'updatejails':
543
391
        print """sudo python setup.py updatejails [--dry|-n]
555
403
    # We build two separate lists, by walking www and console
556
404
    list_www = build_list_py_files('www')
557
405
    list_lib = build_list_py_files('lib')
 
406
    list_scripts = build_list_py_files('scripts')
558
407
    list_subjects = build_list_py_files('subjects', no_top_level=True)
559
 
    list_exercises = build_list_py_files('exercises', no_top_level=True)
560
 
    list_scripts = [
561
 
        "scripts/python-console",
562
 
        "scripts/fileservice",
563
 
        "scripts/serveservice",
564
 
        "scripts/usrmgt-server",
565
 
        "scripts/diffservice",
566
 
    ]
 
408
    list_problems = build_list_py_files('problems', no_top_level=True)
567
409
    # Make sure that the files generated by conf are in the list
568
410
    # (since listmake is typically run before conf)
569
411
    if "lib/conf/conf.py" not in list_lib:
570
 
        list_lib.append("lib/conf/conf.py")
 
412
        list_www.append("lib/conf/conf.py")
 
413
    # Make sure that console/python-console is in the list
 
414
    if "scripts/python-console" not in list_scripts:
 
415
        list_scripts.append("scripts/python-console")
 
416
    if "scripts/fileservice" not in list_scripts:
 
417
        list_scripts.append("scripts/fileservice")
571
418
    # Write these out to a file
572
419
    cwd = os.getcwd()
573
420
    # the files that will be created/overwritten
600
447
list_subjects = """)
601
448
        writelist_pretty(file, list_subjects)
602
449
        file.write("""
603
 
# List of all installable files in exercises directory.
 
450
# List of all installable files in problems directory.
604
451
# This is to install sample exercise material.
605
 
list_exercises = """)
606
 
        writelist_pretty(file, list_exercises)
 
452
list_problems = """)
 
453
        writelist_pretty(file, list_problems)
607
454
 
608
455
        file.close()
609
456
    except IOError, (errno, strerror):
649
496
        file.write(']\n')
650
497
 
651
498
def conf(args):
652
 
    global db_port, usrmgt_port
 
499
    global db_port
653
500
    # Set up some variables
654
501
 
655
502
    cwd = os.getcwd()
656
503
    # the files that will be created/overwritten
657
504
    conffile = os.path.join(cwd, "lib/conf/conf.py")
658
 
    jailconffile = os.path.join(cwd, "lib/conf/jailconf.py")
659
505
    conf_hfile = os.path.join(cwd, "trampoline/conf.h")
660
 
    phpBBconffile = os.path.join(cwd, "www/php/phpBB3/config.php")
661
 
    usrmgtserver_initdfile = os.path.join(cwd, "doc/setup/usrmgt-server.init")
662
506
 
663
507
    # Get command-line arguments to avoid asking questions.
664
508
 
677
521
        print """This tool will create the following files:
678
522
    %s
679
523
    %s
680
 
    %s
681
 
    %s
682
 
    %s
683
524
prompting you for details about your configuration. The file will be
684
525
overwritten if it already exists. It will *not* install or deploy IVLE.
685
526
 
686
527
Please hit Ctrl+C now if you do not wish to do this.
687
 
""" % (conffile, jailconffile, conf_hfile, phpBBconffile, usrmgtserver_initdfile)
 
528
""" % (conffile, conf_hfile)
688
529
 
689
530
        # Get information from the administrator
690
531
        # If EOF is encountered at any time during the questioning, just exit
716
557
        "Invalid DB port (%s).\n"
717
558
        "Must be an integer between 0 and 65535." % repr(db_port))
718
559
        return 1
719
 
    try:
720
 
        usrmgt_port = int(usrmgt_port)
721
 
        if usrmgt_port < 0 or usrmgt_port >= 65536: raise ValueError()
722
 
    except ValueError:
723
 
        print >>sys.stderr, (
724
 
        "Invalid user management port (%s).\n"
725
 
        "Must be an integer between 0 and 65535." % repr(usrmgt_port))
726
 
        return 1
727
 
 
728
 
    # Generate the forum secret
729
 
    forum_secret = hashlib.md5(uuid.uuid4().bytes).hexdigest()
730
560
 
731
561
    # Write lib/conf/conf.py
732
562
 
742
572
            conf.write('%s\n%s = %s\n' % (opt.comment, opt.option_name,
743
573
                repr(globals()[opt.option_name])))
744
574
 
745
 
        # Add the forum secret to the config file (regenerated each config)
746
 
        conf.write('forum_secret = "%s"\n' % (forum_secret))
747
 
 
748
575
        conf.close()
749
576
    except IOError, (errno, strerror):
750
577
        print "IO error(%s): %s" % (errno, strerror)
752
579
 
753
580
    print "Successfully wrote lib/conf/conf.py"
754
581
 
755
 
    # Write conf/jailconf.py
756
 
 
757
 
    try:
758
 
        conf = open(jailconffile, "w")
759
 
 
760
 
        # In the "in-jail" version of conf, we don't need MOST of the details
761
 
        # (it would be a security risk to have them here).
762
 
        # So we just write root_dir, and jail_base is "/".
763
 
        # (jail_base being "/" means "jail-relative" paths are relative to "/"
764
 
        # when inside the jail.)
765
 
        conf.write("""# IVLE Configuration File
766
 
# conf.py
767
 
# Miscellaneous application settings
768
 
# (User jail version)
769
 
 
770
 
 
771
 
# In URL space, where in the site is IVLE located. (All URLs will be prefixed
772
 
# with this).
773
 
# eg. "/" or "/ivle".
774
 
root_dir = %s
775
 
 
776
 
# In the local file system, where are the student/user file spaces located.
777
 
# The user jails are expected to be located immediately in subdirectories of
778
 
# this location.
779
 
jail_base = '/'
780
 
 
781
 
# The hostname for serving publicly accessible pages
782
 
public_host = %s
783
 
""" % (repr(root_dir),repr(public_host)))
784
 
 
785
 
        conf.close()
786
 
    except IOError, (errno, strerror):
787
 
        print "IO error(%s): %s" % (errno, strerror)
788
 
        sys.exit(1)
789
 
 
790
 
    print "Successfully wrote lib/conf/jailconf.py"
791
 
 
792
582
    # Write trampoline/conf.h
793
583
 
794
584
    try:
812
602
 * (Note that root is an implicit member of this list).
813
603
 */
814
604
static const int allowed_uids[] = { %s };
815
 
""" % (repr(jail_base)[1:-1], repr(allowed_uids_list)[1:-1]))
816
 
    # Note: The above uses PYTHON reprs, not C reprs
817
 
    # However they should be the same with the exception of the outer
818
 
    # characters, which are stripped off and replaced
 
605
""" % (jail_base, repr(allowed_uids_list)[1:-1]))
819
606
 
820
607
        conf.close()
821
608
    except IOError, (errno, strerror):
824
611
 
825
612
    print "Successfully wrote trampoline/conf.h"
826
613
 
827
 
    # Write www/php/phpBB3/config.php
828
 
 
829
 
    try:
830
 
        conf = open(phpBBconffile, "w")
831
 
        
832
 
        # php-pg work around
833
 
        if db_host == 'localhost':
834
 
            forumdb_host = '127.0.0.1'
835
 
        else:
836
 
            forumdb_host = db_host
837
 
 
838
 
        conf.write( """<?php
839
 
// phpBB 3.0.x auto-generated configuration file
840
 
// Do not change anything in this file!
841
 
$dbms = 'postgres';
842
 
$dbhost = '""" + forumdb_host + """';
843
 
$dbport = '""" + str(db_port) + """';
844
 
$dbname = '""" + db_forumdbname + """';
845
 
$dbuser = '""" + db_user + """';
846
 
$dbpasswd = '""" + db_password + """';
847
 
 
848
 
$table_prefix = 'phpbb_';
849
 
$acm_type = 'file';
850
 
$load_extensions = '';
851
 
@define('PHPBB_INSTALLED', true);
852
 
// @define('DEBUG', true);
853
 
//@define('DEBUG_EXTRA', true);
854
 
 
855
 
$forum_secret = '""" + forum_secret +"""';
856
 
?>"""   )
857
 
    
858
 
        conf.close()
859
 
    except IOError, (errno, strerror):
860
 
        print "IO error(%s): %s" % (errno, strerror)
861
 
        sys.exit(1)
862
 
 
863
 
    print "Successfully wrote www/php/phpBB3/config.php"
864
 
 
865
 
    # Write lib/conf/usrmgt-server.init
866
 
 
867
 
    try:
868
 
        conf = open(usrmgtserver_initdfile, "w")
869
 
 
870
 
        conf.write( '''#! /bin/sh
871
 
 
872
 
# Works for Ubuntu. Check before using on other distributions
873
 
 
874
 
### BEGIN INIT INFO
875
 
# Provides:          usrmgt-server
876
 
# Required-Start:    $syslog $networking $urandom
877
 
# Required-Stop:     $syslog
878
 
# Default-Start:     2 3 4 5
879
 
# Default-Stop:      1
880
 
# Short-Description: IVLE user management server
881
 
# Description:       Daemon connecting to the IVLE user management database.
882
 
### END INIT INFO
883
 
 
884
 
PATH=/sbin:/bin:/usr/sbin:/usr/bin
885
 
DESC="IVLE user management server"
886
 
NAME=usrmgt-server
887
 
DAEMON=/opt/ivle/scripts/$NAME
888
 
DAEMON_ARGS="''' + str(usrmgt_port) + ''' ''' + usrmgt_magic + '''"
889
 
PIDFILE=/var/run/$NAME.pid
890
 
SCRIPTNAME=/etc/init.d/usrmgt-server
891
 
 
892
 
# Exit if the daemon does not exist 
893
 
test -f $DAEMON || exit 0
894
 
 
895
 
# Load the VERBOSE setting and other rcS variables
896
 
[ -f /etc/default/rcS ] && . /etc/default/rcS
897
 
 
898
 
# Define LSB log_* functions.
899
 
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
900
 
. /lib/lsb/init-functions
901
 
 
902
 
#
903
 
# Function that starts the daemon/service
904
 
#
905
 
do_start()
906
 
{
907
 
        # Return
908
 
        #   0 if daemon has been started
909
 
        #   1 if daemon was already running
910
 
        #   2 if daemon could not be started
911
 
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
912
 
                || return 1
913
 
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
914
 
                $DAEMON_ARGS \
915
 
                || return 2
916
 
        # Add code here, if necessary, that waits for the process to be ready
917
 
        # to handle requests from services started subsequently which depend
918
 
        # on this one.  As a last resort, sleep for some time.
919
 
}
920
 
 
921
 
#
922
 
# Function that stops the daemon/service
923
 
#
924
 
do_stop()
925
 
{
926
 
        # Return
927
 
        #   0 if daemon has been stopped
928
 
        #   1 if daemon was already stopped
929
 
        #   2 if daemon could not be stopped
930
 
        #   other if a failure occurred
931
 
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
932
 
        RETVAL="$?"
933
 
        [ "$RETVAL" = 2 ] && return 2
934
 
        # Wait for children to finish too if this is a daemon that forks
935
 
        # and if the daemon is only ever run from this initscript.
936
 
        # If the above conditions are not satisfied then add some other code
937
 
        # that waits for the process to drop all resources that could be
938
 
        # needed by services started subsequently.  A last resort is to
939
 
        # sleep for some time.
940
 
        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
941
 
        [ "$?" = 2 ] && return 2
942
 
        # Many daemons don't delete their pidfiles when they exit.
943
 
        rm -f $PIDFILE
944
 
        return "$RETVAL"
945
 
}
946
 
 
947
 
#
948
 
# Function that sends a SIGHUP to the daemon/service
949
 
#
950
 
do_reload() {
951
 
        #
952
 
        # If the daemon can reload its configuration without
953
 
        # restarting (for example, when it is sent a SIGHUP),
954
 
        # then implement that here.
955
 
        #
956
 
        start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
957
 
        return 0
958
 
}
959
 
 
960
 
case "$1" in
961
 
  start)
962
 
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
963
 
        do_start
964
 
        case "$?" in
965
 
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
966
 
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
967
 
        esac
968
 
        ;;
969
 
  stop)
970
 
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
971
 
        do_stop
972
 
        case "$?" in
973
 
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
974
 
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
975
 
        esac
976
 
        ;;
977
 
  #reload|force-reload)
978
 
        #
979
 
        # If do_reload() is not implemented then leave this commented out
980
 
        # and leave 'force-reload' as an alias for 'restart'.
981
 
        #
982
 
        #log_daemon_msg "Reloading $DESC" "$NAME"
983
 
        #do_reload
984
 
        #log_end_msg $?
985
 
        #;;
986
 
  restart|force-reload)
987
 
        #
988
 
        # If the "reload" option is implemented then remove the
989
 
        # 'force-reload' alias
990
 
        #
991
 
        log_daemon_msg "Restarting $DESC" "$NAME"
992
 
        do_stop
993
 
        case "$?" in
994
 
          0|1)
995
 
                do_start
996
 
                case "$?" in
997
 
                        0) log_end_msg 0 ;;
998
 
                        1) log_end_msg 1 ;; # Old process is still running
999
 
                        *) log_end_msg 1 ;; # Failed to start
1000
 
                esac
1001
 
                ;;
1002
 
          *)
1003
 
                # Failed to stop
1004
 
                log_end_msg 1
1005
 
                ;;
1006
 
        esac
1007
 
        ;;
1008
 
  *)
1009
 
        #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
1010
 
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
1011
 
        exit 3
1012
 
        ;;
1013
 
esac
1014
 
 
1015
 
:
1016
 
''')
1017
 
        
1018
 
        conf.close()
1019
 
    except IOError, (errno, strerror):
1020
 
        print "IO error(%s): %s" % (errno, strerror)
1021
 
        sys.exit(1)
1022
 
 
1023
 
    # fix permissions as the file contains the database password
1024
 
    try:
1025
 
        os.chmod('doc/setup/usrmgt-server.init', 0600)
1026
 
    except OSError, (errno, strerror):
1027
 
        print "WARNING: Couldn't chmod doc/setup/usrmgt-server.init:"
1028
 
        print "OS error(%s): %s" % (errno, strerror)
1029
 
 
1030
 
    print "Successfully wrote lib/conf/usrmgt-server.init"
1031
 
 
1032
614
    print
1033
615
    print "You may modify the configuration at any time by editing"
1034
616
    print conffile
1035
 
    print jailconffile
1036
617
    print conf_hfile
1037
 
    print phpBBconffile
1038
 
    print usrmgtserver_initdfile
1039
618
    print
1040
619
    return 0
1041
620
 
1047
626
 
1048
627
    if dry:
1049
628
        print "Dry run (no actions will be executed\n"
1050
 
    
1051
 
    # Find out the revison number
1052
 
    revnum = get_svn_revision()
1053
 
    print "Building Revision %s"%str(revnum)
1054
 
    if not dry:
1055
 
        vfile = open('BUILD-VERSION','w')
1056
 
        vfile.write(str(revnum) + '\n')
1057
 
        vfile.close()
1058
629
 
1059
630
    # Compile the trampoline
1060
631
    curdir = os.getcwd()
1068
639
    action_mkdir('jail/home', dry)
1069
640
    action_mkdir('jail/tmp', dry)
1070
641
 
1071
 
    # Chmod the tmp directory to world writable
1072
 
    action_chmod_w('jail/tmp', dry)
1073
 
 
1074
642
    # Copy all console and operating system files into the jail
1075
643
    action_copylist(install_list.list_scripts, 'jail/opt/ivle', dry)
1076
644
    copy_os_files_jail(dry)
1077
645
    # Chmod the python console
1078
646
    action_chmod_x('jail/opt/ivle/scripts/python-console', dry)
1079
647
    action_chmod_x('jail/opt/ivle/scripts/fileservice', dry)
1080
 
    action_chmod_x('jail/opt/ivle/scripts/serveservice', dry)
1081
648
    
1082
 
    # Also copy the IVLE lib directory into the jail
1083
 
    # This is necessary for running certain scripts
1084
 
    action_copylist(install_list.list_lib, 'jail/opt/ivle', dry)
1085
 
    # IMPORTANT: The file jail/opt/ivle/lib/conf/conf.py contains details
1086
 
    # which could compromise security if left in the jail (such as the DB
1087
 
    # password).
1088
 
    # The "safe" version is in jailconf.py. Delete conf.py and replace it with
1089
 
    # jailconf.py.
1090
 
    action_copyfile('lib/conf/jailconf.py',
1091
 
        'jail/opt/ivle/lib/conf/conf.py', dry)
1092
649
 
1093
650
    # Compile .py files into .pyc or .pyo files
1094
651
    compileall.compile_dir('www', quiet=True)
1095
 
    compileall.compile_dir('lib', quiet=True)
1096
 
    compileall.compile_dir('scripts', quiet=True)
1097
 
    compileall.compile_dir('jail/opt/ivle/lib', quiet=True)
1098
 
 
1099
 
    # Set up ivle.pth inside the jail
1100
 
    # Need to set /opt/ivle/lib to be on the import path
1101
 
    ivle_pth = \
1102
 
        "jail/usr/lib/python%s/site-packages/ivle.pth" % PYTHON_VERSION
1103
 
    f = open(ivle_pth, 'w')
1104
 
    f.write('/opt/ivle/lib\n')
1105
 
    f.close()
 
652
    compileall.compile_dir('console', quiet=True)
1106
653
 
1107
654
    return 0
1108
655
 
1150
697
    # chown trampoline to root and set setuid bit
1151
698
    action_chown_setuid(tramppath, dry)
1152
699
 
1153
 
    # Create a scripts directory to put the usrmgt-server in.
1154
 
    action_mkdir(os.path.join(ivle_install_dir, 'scripts'), dry)
1155
 
    usrmgtpath = os.path.join(ivle_install_dir, 'scripts/usrmgt-server')
1156
 
    action_copyfile('scripts/usrmgt-server', usrmgtpath, dry)
1157
 
    action_chmod_x(usrmgtpath, dry)
1158
 
 
1159
700
    # Copy the www and lib directories using the list
1160
701
    action_copylist(install_list.list_www, ivle_install_dir, dry)
1161
702
    action_copylist(install_list.list_lib, ivle_install_dir, dry)
1162
 
    
1163
 
    # Copy the php directory
1164
 
    forum_dir = "www/php/phpBB3"
1165
 
    forum_path = os.path.join(ivle_install_dir, forum_dir)
1166
 
    action_copytree(forum_dir, forum_path, dry)
1167
 
    print "chown -R www-data:www-data %s" % forum_path
1168
 
    if not dry:
1169
 
        os.system("chown -R www-data:www-data %s" % forum_path)
1170
703
 
1171
704
    if not nojail:
1172
705
        # Copy the local jail directory built by the build action
1173
 
        # to the jails __staging__ directory (it will be used to help build
1174
 
        # all the students' jails).
1175
 
        action_copytree('jail', os.path.join(jail_base, '__staging__'), dry)
 
706
        # to the jails template directory (it will be used as a template
 
707
        # for all the students' jails).
 
708
        action_copytree('jail', os.path.join(jail_base, 'template'), dry)
1176
709
    if not nosubjects:
1177
 
        # Copy the subjects and exercises directories across
 
710
        # Copy the subjects and problems directories across
1178
711
        action_copylist(install_list.list_subjects, subjects_base, dry,
1179
712
            srcdir="./subjects")
1180
 
        action_copylist(install_list.list_exercises, exercises_base, dry,
1181
 
            srcdir="./exercises")
 
713
        action_copylist(install_list.list_problems, problems_base, dry,
 
714
            srcdir="./problems")
1182
715
 
1183
716
    # Append IVLE path to ivle.pth in python site packages
1184
717
    # (Unless it's already there)
1219
752
        print >>sys.stderr, "(I need to chown some files)."
1220
753
        return 1
1221
754
 
1222
 
    # Update the staging jail directory in case it hasn't been installed
 
755
    # Update the template jail directory in case it hasn't been installed
1223
756
    # recently.
1224
 
    action_copytree('jail', os.path.join(jail_base, '__staging__'), dry)
 
757
    action_copytree('jail', os.path.join(jail_base, 'template'), dry)
1225
758
 
1226
759
    # Re-link all the files in all students jails.
1227
760
    for dir in os.listdir(jail_base):
1228
 
        if dir == '__staging__': continue
 
761
        if dir == 'template': continue
1229
762
        # First back up the student's home directory
1230
763
        temp_home = os.tmpnam()
1231
764
        action_rename(os.path.join(jail_base, dir, 'home'), temp_home, dry)
1232
765
        # Delete the student's jail and relink the jail files
1233
 
        action_linktree(os.path.join(jail_base, '__staging__'),
 
766
        action_linktree(os.path.join(jail_base, 'template'),
1234
767
            os.path.join(jail_base, dir), dry)
1235
768
        # Restore the student's home directory
1236
769
        action_rename(temp_home, os.path.join(jail_base, dir, 'home'), dry)
1269
802
    if ret != 0:
1270
803
        raise RunError(prog, ret)
1271
804
 
1272
 
def action_remove(path, dry):
1273
 
    """Calls rmtree, deleting the target file if it exists."""
1274
 
    try:
1275
 
        print "rm -r", path
1276
 
        if not dry:
1277
 
            shutil.rmtree(path, True)
1278
 
    except OSError, (err, msg):
1279
 
        if err != errno.EEXIST:
1280
 
            raise
1281
 
        # Otherwise, didn't exist, so we don't care
1282
 
 
1283
805
def action_rename(src, dst, dry):
1284
806
    """Calls rename. Deletes the target if it already exists."""
1285
 
    action_remove(dst, dry)
 
807
    if os.access(dst, os.F_OK):
 
808
        print "rm -r", dst
 
809
        if not dry:
 
810
            shutil.rmtree(dst, True)
1286
811
    print "mv ", src, dst
1287
812
    if dry: return
1288
813
    try:
1308
833
    directories as necessary.
1309
834
 
1310
835
    See shutil.copytree."""
1311
 
    # Allow copying over itself
1312
 
    if (os.path.normpath(os.path.join(os.getcwd(),src)) ==
1313
 
        os.path.normpath(os.path.join(os.getcwd(),dst))):
1314
 
        return
1315
 
    action_remove(dst, dry)
 
836
    if os.access(dst, os.F_OK):
 
837
        print "rm -r", dst
 
838
        if not dry:
 
839
            shutil.rmtree(dst, True)
1316
840
    print "cp -r", src, dst
1317
841
    if dry: return
1318
842
    shutil.copytree(src, dst, True)
1321
845
    """Hard-links an entire directory tree. Same as copytree but the created
1322
846
    files are hard-links not actual copies. Removes the existing destination.
1323
847
    """
1324
 
    action_remove(dst, dry)
 
848
    if os.access(dst, os.F_OK):
 
849
        print "rm -r", dst
 
850
        if not dry:
 
851
            shutil.rmtree(dst, True)
1325
852
    print "<cp with hardlinks> -r", src, dst
1326
853
    if dry: return
1327
854
    common.makeuser.linktree(src, dst)
1402
929
        os.chmod(file, stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR
1403
930
            | stat.S_IXGRP | stat.S_IRGRP | stat.S_IXOTH | stat.S_IROTH)
1404
931
 
1405
 
 
1406
 
def action_chmod_w(file, dry):
1407
 
    """Chmod 777 a file (sets permissions to rwxrwxrwx)."""
1408
 
    print "chmod 777", file
1409
 
    if not dry:
1410
 
        os.chmod(file, stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR
1411
 
            | stat.S_IXGRP | stat.S_IWGRP | stat.S_IRGRP | stat.S_IXOTH
1412
 
            | stat.S_IWOTH | stat.S_IROTH)
1413
 
 
1414
932
def query_user(default, prompt):
1415
933
    """Prompts the user for a string, which is read from a line of stdin.
1416
934
    Exits silently if EOF is encountered. Returns the string, with spaces
1443
961
            del list[i]
1444
962
        i -= 1
1445
963
 
1446
 
def get_svn_revision():
1447
 
    """Returns either the current SVN revision of this build, or None"""
1448
 
    try:
1449
 
        svn = pysvn.Client()
1450
 
        entry = svn.info('.')
1451
 
        revnum = entry.revision.number
1452
 
    except pysvn.ClientError, e:
1453
 
        revnum = None
1454
 
    return revnum
1455
 
 
1456
964
if __name__ == "__main__":
1457
965
    sys.exit(main())
1458