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

« back to all changes in this revision

Viewing changes to bin/ivle-buildjail

  • Committer: Matt Giuca
  • Date: 2009-12-08 05:05:20 UTC
  • Revision ID: matt.giuca@gmail.com-20091208050520-a4nmmjxwtmhip063
ivle-createdatadirs: Fixed exit -- if path already exists, log and exit(0).

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
import optparse
20
20
import os
 
21
import stat
21
22
import sys
22
23
import shutil
23
24
 
24
25
import ivle.conf
 
26
import ivle.config
 
27
import ivle.jailbuilder.debian
 
28
 
 
29
class UnsafeJail(Exception):
 
30
    pass
25
31
 
26
32
usage = """usage: %prog [options]
27
33
(requires root)
28
34
Builds or updates the base IVLE jail."""
29
35
 
 
36
conf = ivle.config.Config()
 
37
build_path = ivle.conf.jail_system_build
 
38
 
30
39
# Parse arguments
31
40
parser = optparse.OptionParser(usage)
32
41
parser.add_option("-r", "--recreate",
33
42
    action="store_true", dest="recreate",
34
43
    help='''Completely recreate the jail - don't just update its IVLE code.
35
44
Be warned, this may download hundreds of megabytes!''')
 
45
parser.add_option("-u", "--upgrade",
 
46
    action="store_true", dest="upgrade",
 
47
    help='''Apply any package updates in the jail.''')
36
48
parser.add_option("-m", "--mirror",
37
49
    action="store", dest="apt_mirror",
38
 
    help="Sets the apt mirror used when recreating the jail.")
 
50
    help="Sets the apt mirror.", default=conf['jail']['mirror'])
 
51
parser.add_option("--python-site-packages",
 
52
    action="store", dest="python_site_packages",
 
53
    help="Path to Python site packages directory inside the jail.",
 
54
    default=None)
39
55
(options, args) = parser.parse_args(sys.argv)
40
56
 
41
57
if os.geteuid() != 0:
42
58
    print >> sys.stderr, "Must be root to run buildjail."
43
59
    sys.exit(1)
44
60
 
45
 
if not options.recreate and not os.path.exists(ivle.conf.jail_system_build):
 
61
if not options.recreate and not os.path.exists(build_path):
46
62
    print >> sys.stderr, "No jail exists -- please rerun with -r."
47
63
    sys.exit(1)
48
64
 
 
65
if (options.python_site_packages is not None and
 
66
    options.python_site_packages[:1] not in (os.path.sep, os.path.altsep)):
 
67
    print >> sys.stderr, "python-site-packages must be an absolute path."
 
68
    sys.exit(1)
 
69
 
49
70
if options.recreate:
 
71
    options.upgrade = True
 
72
 
50
73
    # Create the jail and its subdirectories
51
74
    # Note: Other subdirs will be made by copying files
52
75
    if options.apt_mirror is not None:
53
76
        os.environ['MIRROR'] = options.apt_mirror
54
77
 
55
 
    # XXX: buildjail.sh should be reimplemented in Python, with its envvars
56
 
    # turned into config options.
57
 
    if os.spawnvp(os.P_WAIT, 'setup/buildjail.sh',
58
 
                  ['setup/buildjail.sh', ivle.conf.jail_system_build]) != 0:
59
 
        print >> sys.stderr, "Jail creation failed."
60
 
        sys.exit(1)
61
 
 
62
 
# Copy all console and operating system files into the jail
63
 
services_path = os.path.join(ivle.conf.share_path, 'services')
64
 
jail_services_path = os.path.join(ivle.conf.jail_system_build,
65
 
                                  services_path[1:])
66
 
if os.path.exists(jail_services_path):
67
 
    shutil.rmtree(jail_services_path)
68
 
shutil.copytree(services_path, jail_services_path)
69
 
 
70
 
# Also copy the IVLE lib directory into the jail
71
 
# This is necessary for running certain services
72
 
ivle_site_packages = os.path.join(ivle.conf.python_site_packages, 'ivle')
73
 
jail_site_packages = os.path.join(ivle.conf.jail_system_build,
74
 
                                  ivle_site_packages[1:])
75
 
if os.path.exists(jail_site_packages):
76
 
    shutil.rmtree(jail_site_packages)
77
 
shutil.copytree(ivle_site_packages, jail_site_packages)
78
 
 
79
 
# IMPORTANT: ivle/conf/conf.py contains details which could compromise security
80
 
# if left in the jail (such as the DB password). We delete it now! It would be
81
 
# shadowed by the per-user conf.py anyway, but it's best to be safe.
82
 
os.unlink(os.path.join(jail_site_packages, 'conf/conf.py'))
83
 
# XXX: Shouldn't copy the compiled files at all, but compile them in the jail!
84
 
os.unlink(os.path.join(jail_site_packages, 'conf/conf.pyc'))
 
78
    os.system('rm -rf --one-file-system ' + build_path)
 
79
    ivle.jailbuilder.debian.debootstrap_create_jail(conf['jail']['suite'],
 
80
              build_path, mirror=options.apt_mirror)
 
81
 
 
82
    ivle.jailbuilder.debian.apt_update_cache(build_path)
 
83
    ivle.jailbuilder.debian.apt_install(build_path,
 
84
                        ['python2.5', 'python-cjson', 'python-svn'])
 
85
 
 
86
    ivle.jailbuilder.debian.apt_clean(build_path)
 
87
 
 
88
if options.upgrade:
 
89
    # Run apt-get update, apt-get upgrade and apt-get clean.
 
90
    ivle.jailbuilder.debian.mangle_sources_list(build_path, clobber=True)
 
91
    ivle.jailbuilder.debian.mangle_sources_list(build_path, lines=[
 
92
            'deb %s %s%s %s' % (options.apt_mirror, conf['jail']['suite'],
 
93
                                pocket, ' '.join(['main', 'universe']))
 
94
            for pocket in ('', '-updates', '-security')])
 
95
 
 
96
    # Add any extra site apt sources.
 
97
    if conf['jail']['extra_sources']:
 
98
        ivle.jailbuilder.debian.mangle_sources_list(build_path,
 
99
                  conf['jail']['extra_sources'])
 
100
 
 
101
    # Add any extra site apt keys.
 
102
    if conf['jail']['extra_keys']:
 
103
        ivle.jailbuilder.debian.apt_add_key(build_path,
 
104
                                            conf['jail']['extra_keys'])
 
105
 
 
106
    ivle.jailbuilder.debian.apt_update_cache(build_path)
 
107
    ivle.jailbuilder.debian.apt_upgrade(build_path)
 
108
 
 
109
    # Install any extra site packages.
 
110
    if conf['jail']['extra_packages']:
 
111
        ivle.jailbuilder.debian.apt_install(build_path,
 
112
                  conf['jail']['extra_packages'])
 
113
 
 
114
    ivle.jailbuilder.debian.apt_clean(build_path)
 
115
 
 
116
if conf['jail']['devmode']:
 
117
    # Copy all console and operating system files into the jail
 
118
    services_path = os.path.join(ivle.conf.share_path, 'services')
 
119
    jail_services_path = os.path.join(build_path, services_path[1:])
 
120
    if os.path.exists(jail_services_path):
 
121
        shutil.rmtree(jail_services_path)
 
122
    shutil.copytree(services_path, jail_services_path)
 
123
 
 
124
    # Also copy the IVLE lib directory into the jail
 
125
    # This is necessary for running certain services
 
126
 
 
127
    # ivle_site_packages is the IVLE install location outside the jail
 
128
    ivle_site_packages = os.path.dirname(ivle.__file__)
 
129
 
 
130
    if options.python_site_packages is None:
 
131
        # Get the site packages from the IVLE install location *OUTSIDE* the
 
132
        # jail. Warning! This only works if you have the same Python site
 
133
        # packages directory inside and out (ie. same Python version).
 
134
        # If not, you should use --python-site-packages.
 
135
        jail_site_packages = os.path.join(build_path, ivle_site_packages[1:])
 
136
    else:
 
137
        # User-specified site packages
 
138
        jail_site_packages = os.path.join(build_path,
 
139
                                options.python_site_packages[1:], "ivle")
 
140
    if os.path.exists(jail_site_packages):
 
141
        shutil.rmtree(jail_site_packages)
 
142
    shutil.copytree(ivle_site_packages, jail_site_packages)
 
143
 
 
144
# Make /tmp and /var/lock un-world-writable. /tmp will be mounted over,
 
145
# and /var/{lock,tmp} should die.
 
146
for path in ('tmp', 'var/lock', 'var/tmp'):
 
147
    path = os.path.join(build_path, path)
 
148
    os.chmod(path, os.stat(path).st_mode & ~stat.S_IWOTH)
 
149
 
 
150
# Verify that nothing in the jail is world-writable.
 
151
# We don't want students to write into places that others can see.
 
152
for path, dirs, files in os.walk(build_path):
 
153
    for dname in dirs:
 
154
        d = os.path.join(path, dname)
 
155
        if os.path.islink(d):
 
156
            continue
 
157
        if os.stat(d).st_mode & stat.S_IWOTH:
 
158
            raise UnsafeJail(d)
 
159
 
 
160
    for fname in files:
 
161
        f = os.path.join(path, fname)
 
162
        if os.path.islink(f):
 
163
            continue
 
164
        if os.stat(f).st_mode & stat.S_IWOTH:
 
165
            if (os.path.dirname(f) == os.path.join(build_path, 'dev') and
 
166
                os.path.basename(f) in ('ptmx', 'null', 'tty', 'full', 'zero',
 
167
                                        'random', 'urandom')
 
168
                ):
 
169
                continue
 
170
            raise UnsafeJail(f)
 
171
    
85
172
 
86
173
if os.spawnvp(os.P_WAIT, 'rsync', ['rsync', '-a', '--delete',
87
 
              ivle.conf.jail_system_build + '/', ivle.conf.jail_system]) != 0:
 
174
              build_path + '/', ivle.conf.jail_system]) != 0:
88
175
    print >> sys.stderr, "Jail copying failed."
89
176
    sys.exit(1)
90
177
 
 
178
# Now mangle things a bit, so we can bind-mount the user bits in.
 
179
# /etc/passwd and /etc/ivle/ivle.conf need to be symlinks to somewhere in /home
 
180
 
 
181
os.rename(os.path.join(ivle.conf.jail_system, 'etc/passwd'),
 
182
          os.path.join(ivle.conf.jail_system, 'home/.passwd')
 
183
          )
 
184
os.symlink('../home/.passwd', os.path.join(ivle.conf.jail_system, 'etc/passwd'))
 
185
 
 
186
os.makedirs(os.path.join(ivle.conf.jail_system, "etc/ivle"))
 
187
os.symlink('../../home/.ivle.conf',
 
188
           os.path.join(ivle.conf.jail_system, "etc/ivle/ivle.conf"))