71
# Import modules from the website is tricky since they're in the www
73
sys.path.append(os.path.join(os.getcwd(), 'www'))
75
import common.makeuser
77
# Operating system files to copy over into the jail.
78
# These will be copied from the given place on the OS file system into the
79
# same place within the jail.
82
'/lib/tls/i686/cmov/libc.so.6',
83
'/lib/tls/i686/cmov/libdl.so.2',
84
'/lib/tls/i686/cmov/libm.so.6',
85
'/lib/tls/i686/cmov/libpthread.so.0',
86
'/lib/tls/i686/cmov/libutil.so.1',
89
# These 2 files do not exist in Ubuntu
90
#'/etc/ld.so.preload',
91
#'/etc/ld.so.nohwcap',
98
# Needed by matplotlib
99
'/usr/lib/i686/cmov/libssl.so.0.9.8',
100
'/usr/lib/i686/cmov/libcrypto.so.0.9.8',
101
'/lib/tls/i686/cmov/libnsl.so.1',
102
'/usr/lib/libz.so.1',
103
'/usr/lib/atlas/liblapack.so.3',
104
'/usr/lib/atlas/libblas.so.3',
105
'/usr/lib/libg2c.so.0',
106
'/usr/lib/libstdc++.so.6',
107
'/usr/lib/libfreetype.so.6',
108
'/usr/lib/libpng12.so.0',
109
'/usr/lib/libBLT.2.4.so.8.4',
110
'/usr/lib/libtk8.4.so.0',
111
'/usr/lib/libtcl8.4.so.0',
112
'/usr/lib/tcl8.4/init.tcl',
113
'/usr/lib/libX11.so.6',
114
'/usr/lib/libXau.so.6',
115
'/usr/lib/libXdmcp.so.6',
116
'/lib/libgcc_s.so.1',
119
# Symlinks to make within the jail. Src mapped to dst.
121
'python2.5': 'jail/usr/bin/python',
123
# Trees to copy. Src mapped to dst (these will be passed to action_copytree).
125
'/usr/lib/python2.5': 'jail/usr/lib/python2.5',
126
'/usr/share/matplotlib': 'jail/usr/share/matplotlib',
127
'/etc/ld.so.conf.d': 'jail/etc/ld.so.conf.d',
71
130
# Try importing existing conf, but if we can't just set up defaults
72
131
# The reason for this is that these settings are used by other phases
73
132
# of setup besides conf, so we need to know them.
74
133
# Also this allows you to hit Return to accept the existing value.
76
135
confmodule = __import__("www/conf/conf")
77
root_dir = confmodule.root_dir
78
ivle_install_dir = confmodule.ivle_install_dir
79
jail_base = confmodule.jail_base
137
root_dir = confmodule.root_dir
141
ivle_install_dir = confmodule.ivle_install_dir
143
ivle_install_dir = "/opt/ivle"
145
public_host = confmodule.public_host
147
public_host = "public.localhost"
149
jail_base = confmodule.jail_base
151
jail_base = "/home/informatics/jails"
80
152
except ImportError:
81
153
# Just set reasonable defaults
82
154
root_dir = "/ivle"
83
155
ivle_install_dir = "/opt/ivle"
156
public_host = "public.localhost"
84
157
jail_base = "/home/informatics/jails"
86
159
allowed_uids = "0"
344
423
jail_base = query_user(jail_base,
345
424
"""Root directory where the jails (containing user files) are stored
346
425
(on the local file system):""")
426
public_host = query_user(public_host,
427
"""Hostname which will cause the server to go into "public mode",
428
providing login-free access to student's published work:""")
347
429
allowed_uids = query_user(allowed_uids,
348
430
"""UID of the web server process which will run IVLE.
349
431
Only this user may execute the trampoline. May specify multiple users as
390
474
# This directory should contain the "www" and "bin" directories.
391
475
ivle_install_dir = "%s"
477
# The server goes into "public mode" if the browser sends a request with this
478
# host. This is for security reasons - we only serve public student files on a
479
# separate domain to the main IVLE site.
480
# Public mode does not use cookies, and serves only public content.
481
# Private mode (normal mode) requires login, and only serves files relevant to
482
# the logged-in user.
393
485
# In the local file system, where are the student/user file spaces located.
394
486
# The user jails are expected to be located immediately in subdirectories of
398
# Which application to load by default (if the user navigates to the top level
399
# of the site). This is the app's URL name.
400
# Note that if this app requires authentication, the user will first be
401
# presented with the login screen.
403
""" % (root_dir, ivle_install_dir, jail_base, default_app))
489
""" % (root_dir, ivle_install_dir, public_host, jail_base))
406
492
except IOError, (errno, strerror):
481
570
"""Copies necessary Operating System files from their usual locations
482
571
into the jail/ directory of the cwd."""
483
572
# Currently source paths are configured for Ubuntu.
484
copy_file_to_jail('/lib/ld-linux.so.2', dry)
485
copy_file_to_jail('/lib/tls/i686/cmov/libc.so.6', dry)
486
copy_file_to_jail('/lib/tls/i686/cmov/libdl.so.2', dry)
487
copy_file_to_jail('/lib/tls/i686/cmov/libm.so.6', dry)
488
copy_file_to_jail('/lib/tls/i686/cmov/libpthread.so.0', dry)
489
copy_file_to_jail('/lib/tls/i686/cmov/libutil.so.1', dry)
490
copy_file_to_jail('/usr/bin/python2.5', dry)
491
action_symlink('python2.5', 'jail/usr/bin/python', dry)
492
action_copytree('/usr/lib/python2.5', 'jail/usr/lib/python2.5', dry)
573
for filename in JAIL_FILES:
574
copy_file_to_jail(filename, dry)
575
for src, dst in JAIL_LINKS.items():
576
action_symlink(src, dst, dry)
577
for src, dst in JAIL_COPYTREES.items():
578
action_copytree(src, dst, dry)
494
580
def copy_file_to_jail(src, dry):
495
581
"""Copies a single file from an absolute location into the same location
531
617
# for all the students' jails).
532
618
action_copytree('jail', os.path.join(jail_base, 'template'), dry)
620
# Append IVLE path to ivle.pth in python site packages
621
# (Unless it's already there)
622
ivle_pth = os.path.join(sys.prefix,
623
"lib/python2.5/site-packages/ivle.pth")
624
ivle_www = os.path.join(ivle_install_dir, "www")
625
write_ivle_pth = True
627
file = open(ivle_pth, 'r')
629
if line.strip() == ivle_www:
630
write_ivle_pth = False
632
except (IOError, OSError):
635
action_append(ivle_pth, ivle_www)
639
def updatejails(args):
640
# Get "dry" variable from command line
641
(opts, args) = getopt.gnu_getopt(args, "n", ['dry'])
643
dry = '-n' in opts or '--dry' in opts
646
print "Dry run (no actions will be executed\n"
648
if not dry and os.geteuid() != 0:
649
print >>sys.stderr, "Must be root to run install"
650
print >>sys.stderr, "(I need to chown some files)."
653
# Update the template jail directory in case it hasn't been installed
655
action_copytree('jail', os.path.join(jail_base, 'template'), dry)
657
# Re-link all the files in all students jails.
658
for dir in os.listdir(jail_base):
659
if dir == 'template': continue
660
# First back up the student's home directory
661
temp_home = os.tmpnam()
662
action_rename(os.path.join(jail_base, dir, 'home'), temp_home, dry)
663
# Delete the student's jail and relink the jail files
664
action_linktree(os.path.join(jail_base, 'template'),
665
os.path.join(jail_base, dir), dry)
666
# Restore the student's home directory
667
action_rename(temp_home, os.path.join(jail_base, dir, 'home'), dry)
668
# Set up the user's home directory just in case they don't have a
669
# directory for this yet
670
action_mkdir(os.path.join(jail_base, dir, 'home', dir), dry)
536
674
# The actions call Python os functions but print actions and handle dryness.
563
701
raise RunError(prog, ret)
703
def action_rename(src, dst, dry):
704
"""Calls rename. Deletes the target if it already exists."""
705
if os.access(dst, os.F_OK):
708
shutil.rmtree(dst, True)
709
print "mv ", src, dst
713
except OSError, (err, msg):
714
if err != errno.EEXIST:
565
717
def action_mkdir(path, dry):
566
718
"""Calls mkdir. Silently ignored if the directory already exists.
567
719
Creates all parent directories as necessary."""
588
740
shutil.copytree(src, dst, True)
742
def action_linktree(src, dst, dry):
743
"""Hard-links an entire directory tree. Same as copytree but the created
744
files are hard-links not actual copies. Removes the existing destination.
746
if os.access(dst, os.F_OK):
749
shutil.rmtree(dst, True)
750
print "<cp with hardlinks> -r", src, dst
752
common.makeuser.linktree(src, dst)
590
754
def action_copylist(srclist, dst, dry):
591
755
"""Copies all files in a list to a new location. The files in the list
592
756
are read relative to the current directory, and their destinations are the
648
817
os.chmod(file, stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
649
818
| stat.S_ISUID | stat.S_IRUSR | stat.S_IWUSR)
820
def action_chmod_x(file, dry):
821
"""Chmod +xs a file (sets execute permission)."""
822
print "chmod u+rwx", file
824
os.chmod(file, stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR)
651
826
def query_user(default, prompt):
652
827
"""Prompts the user for a string, which is read from a line of stdin.
653
828
Exits silently if EOF is encountered. Returns the string, with spaces