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
71
77
# Operating system files to copy over into the jail.
72
78
# These will be copied from the given place on the OS file system into the
73
79
# same place within the jail.
159
165
# Disallow run as root unless installing
160
if operation != 'install' and os.geteuid() == 0:
166
if (operation != 'install' and operation != 'updatejails'
167
and os.geteuid() == 0):
161
168
print >>sys.stderr, "I do not want to run this stage as root."
162
169
print >>sys.stderr, "Please run as a normal user."
253
261
--nojail Do not copy the jail.
254
262
--dry | -n Print out the actions but don't do anything."""
263
elif operation == 'updatejails':
264
print """sudo python setup.py updatejails [--dry|-n]
266
Copy jail/ to each subdirectory in jails directory.
268
--dry | -n Print out the actions but don't do anything."""
256
270
print >>sys.stderr, (
257
271
"""Invalid operation '%s'. Try python setup.py help."""
568
def updatejails(args):
569
# Get "dry" variable from command line
570
(opts, args) = getopt.gnu_getopt(args, "n", ['dry'])
572
dry = '-n' in opts or '--dry' in opts
575
print "Dry run (no actions will be executed\n"
577
if not dry and os.geteuid() != 0:
578
print >>sys.stderr, "Must be root to run install"
579
print >>sys.stderr, "(I need to chown some files)."
582
# Update the template jail directory in case it hasn't been installed
584
action_copytree('jail', os.path.join(jail_base, 'template'), dry)
586
# Re-link all the files in all students jails.
587
for dir in os.listdir(jail_base):
588
if dir == 'template': continue
589
# First back up the student's home directory
590
temp_home = os.tmpnam()
591
action_rename(os.path.join(jail_base, dir, 'home'), temp_home, dry)
592
# Delete the student's jail and relink the jail files
593
action_linktree(os.path.join(jail_base, 'template'),
594
os.path.join(jail_base, dir), dry)
595
# Restore the student's home directory
596
action_rename(temp_home, os.path.join(jail_base, dir, 'home'), dry)
597
# Set up the user's home directory just in case they don't have a
598
# directory for this yet
599
action_mkdir(os.path.join(jail_base, dir, 'home', dir), dry)
554
603
# The actions call Python os functions but print actions and handle dryness.
555
604
# May still throw os exceptions if errors occur.
581
630
raise RunError(prog, ret)
632
def action_rename(src, dst, dry):
633
"""Calls rename. Deletes the target if it already exists."""
634
if os.access(dst, os.F_OK):
637
shutil.rmtree(dst, True)
638
print "mv ", src, dst
642
except OSError, (err, msg):
643
if err != errno.EEXIST:
583
646
def action_mkdir(path, dry):
584
647
"""Calls mkdir. Silently ignored if the directory already exists.
585
648
Creates all parent directories as necessary."""
606
669
shutil.copytree(src, dst, True)
671
def action_linktree(src, dst, dry):
672
"""Hard-links an entire directory tree. Same as copytree but the created
673
files are hard-links not actual copies. Removes the existing destination.
675
if os.access(dst, os.F_OK):
678
shutil.rmtree(dst, True)
679
print "<cp with hardlinks> -r", src, dst
681
common.makeuser.linktree(src, dst)
608
683
def action_copylist(srclist, dst, dry):
609
684
"""Copies all files in a list to a new location. The files in the list
610
685
are read relative to the current directory, and their destinations are the