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

« back to all changes in this revision

Viewing changes to setup.py

  • Committer: mattgiuca
  • Date: 2008-01-12 15:35:53 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:201
Added "test" directory.
Added make_date_test.py, a short script I wrote to test the date format
algorithm committed in the previous revision.

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
import compileall
69
69
import getopt
70
70
 
71
 
# Import modules from the website is tricky since they're in the www
72
 
# directory.
73
 
sys.path.append(os.path.join(os.getcwd(), 'www'))
74
 
import conf
75
 
import common.makeuser
76
 
 
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.
80
 
JAIL_FILES = [
81
 
    '/lib/ld-linux.so.2',
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',
87
 
    '/etc/ld.so.conf',
88
 
    '/etc/ld.so.cache',
89
 
    # These 2 files do not exist in Ubuntu
90
 
    #'/etc/ld.so.preload',
91
 
    #'/etc/ld.so.nohwcap',
92
 
    # UNIX commands
93
 
    '/usr/bin/strace',
94
 
    '/bin/ls',
95
 
    '/bin/echo',
96
 
    # Needed by python
97
 
    '/usr/bin/python2.5',
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',
117
 
    '/etc/matplotlibrc',
118
 
]
119
 
# Symlinks to make within the jail. Src mapped to dst.
120
 
JAIL_LINKS = {
121
 
    'python2.5': 'jail/usr/bin/python',
122
 
}
123
 
# Trees to copy. Src mapped to dst (these will be passed to action_copytree).
124
 
JAIL_COPYTREES = {
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',
128
 
}
129
 
 
130
71
# Try importing existing conf, but if we can't just set up defaults
131
72
# The reason for this is that these settings are used by other phases
132
73
# of setup besides conf, so we need to know them.
142
83
    except:
143
84
        ivle_install_dir = "/opt/ivle"
144
85
    try:
145
 
        public_host = confmodule.public_host
146
 
    except:
147
 
        public_host = "public.localhost"
148
 
    try:
149
86
        jail_base = confmodule.jail_base
150
87
    except:
151
88
        jail_base = "/home/informatics/jails"
152
 
    try:
153
 
        subjects_base = confmodule.subjects_base
154
 
    except:
155
 
        subjects_base = "/home/informatics/subjects"
156
89
except ImportError:
157
90
    # Just set reasonable defaults
158
91
    root_dir = "/ivle"
159
92
    ivle_install_dir = "/opt/ivle"
160
 
    public_host = "public.localhost"
161
93
    jail_base = "/home/informatics/jails"
162
 
    subjects_base = "/home/informatics/subjects"
163
94
# Always defaults
164
95
allowed_uids = "0"
165
96
 
176
107
# as necessary, and include it in the distribution.
177
108
listmake_mimetypes = ['text/x-python', 'text/html',
178
109
    'application/x-javascript', 'application/javascript',
179
 
    'text/css', 'image/png', 'application/xml']
 
110
    'text/css', 'image/png']
180
111
 
181
112
# Main function skeleton from Guido van Rossum
182
113
# http://www.artima.com/weblogs/viewpost.jsp?thread=4829
205
136
        return 1
206
137
 
207
138
    # Disallow run as root unless installing
208
 
    if (operation != 'install' and operation != 'updatejails'
209
 
        and os.geteuid() == 0):
 
139
    if operation != 'install' and os.geteuid() == 0:
210
140
        print >>sys.stderr, "I do not want to run this stage as root."
211
141
        print >>sys.stderr, "Please run as a normal user."
212
142
        return 1
218
148
            'build' : build,
219
149
            'listmake' : listmake,
220
150
            'install' : install,
221
 
            'updatejails' : updatejails,
222
151
        }[operation]
223
152
    except KeyError:
224
153
        print >>sys.stderr, (
237
166
    listmake (developer use only)
238
167
    conf [args]
239
168
    build
240
 
    install [--nojail] [--nosubjects] [-n|--dry]
 
169
    install [--nojail] [-n|--dry]
241
170
"""
242
171
        return 1
243
172
    elif len(args) != 1:
272
201
Args are:
273
202
    --root_dir
274
203
    --ivle_install_dir
275
 
    --public_host
276
204
    --jail_base
277
 
    --subjects_base
278
205
    --allowed_uids
279
206
As explained in the interactive prompt or conf.py.
280
207
"""
293
220
 
294
221
--dry | -n  Print out the actions but don't do anything."""
295
222
    elif operation == 'install':
296
 
        print """sudo python setup.py install [--nojail] [--nosubjects][--dry|-n]
 
223
        print """sudo python setup.py install [--nojail] [--dry|-n]
297
224
(Requires root)
298
225
Create target install directory ($target).
299
226
Create $target/bin.
301
228
chown and chmod the installed trampoline.
302
229
Copy www/ to $target.
303
230
Copy jail/ to jails template directory (unless --nojail specified).
304
 
Copy subjects/ to subjects directory (unless --nosubjects specified).
305
 
 
306
 
--nojail        Do not copy the jail.
307
 
--nosubjects    Do not copy the subjects.
308
 
--dry | -n  Print out the actions but don't do anything."""
309
 
    elif operation == 'updatejails':
310
 
        print """sudo python setup.py updatejails [--dry|-n]
311
 
(Requires root)
312
 
Copy jail/ to each subdirectory in jails directory.
313
 
 
 
231
 
 
232
--nojail    Do not copy the jail.
314
233
--dry | -n  Print out the actions but don't do anything."""
315
234
    else:
316
235
        print >>sys.stderr, (
322
241
    # We build two separate lists, by walking www and console
323
242
    list_www = build_list_py_files('www')
324
243
    list_console = build_list_py_files('console')
325
 
    list_subjects = build_list_py_files('subjects', no_top_level=True)
326
244
    # Make sure that the files generated by conf are in the list
327
245
    # (since listmake is typically run before conf)
328
246
    if "www/conf/conf.py" not in list_www:
352
270
# List of all installable files in console directory.
353
271
list_console = """)
354
272
        writelist_pretty(file, list_console)
355
 
        file.write("""
356
 
# List of all installable files in subjects directory.
357
 
# This is to install sample subjects and material.
358
 
list_subjects = """)
359
 
        writelist_pretty(file, list_subjects)
360
273
 
361
274
        file.close()
362
275
    except IOError, (errno, strerror):
373
286
 
374
287
    return 0
375
288
 
376
 
def build_list_py_files(dir, no_top_level=False):
 
289
def build_list_py_files(dir):
377
290
    """Builds a list of all py files found in a directory and its
378
 
    subdirectories. Returns this as a list of strings.
379
 
    no_top_level=True means the file paths will not include the top-level
380
 
    directory.
381
 
    """
 
291
    subdirectories. Returns this as a list of strings."""
382
292
    pylist = []
383
293
    for (dirpath, dirnames, filenames) in os.walk(dir):
384
294
        # Exclude directories beginning with a '.' (such as '.svn')
386
296
        # All *.py files are added to the list
387
297
        pylist += [os.path.join(dirpath, item) for item in filenames
388
298
            if mimetypes.guess_type(item)[0] in listmake_mimetypes]
389
 
    if no_top_level:
390
 
        for i in range(0, len(pylist)):
391
 
            _, pylist[i] = pylist[i].split(os.sep, 1)
392
299
    return pylist
393
300
 
394
301
def writelist_pretty(file, list):
402
309
        file.write(']\n')
403
310
 
404
311
def conf(args):
405
 
    global root_dir, ivle_install_dir, jail_base, subjects_base
406
 
    global public_host, allowed_uids
 
312
    global root_dir, ivle_install_dir, jail_base, allowed_uids
407
313
    # Set up some variables
408
314
 
409
315
    cwd = os.getcwd()
444
350
        jail_base = query_user(jail_base,
445
351
        """Root directory where the jails (containing user files) are stored
446
352
(on the local file system):""")
447
 
        subjects_base = query_user(subjects_base,
448
 
        """Root directory where the subject directories (containing worksheets
449
 
and other per-subject files) are stored (on the local file system):""")
450
 
        public_host = query_user(public_host,
451
 
        """Hostname which will cause the server to go into "public mode",
452
 
providing login-free access to student's published work:""")
453
353
        allowed_uids = query_user(allowed_uids,
454
354
        """UID of the web server process which will run IVLE.
455
355
Only this user may execute the trampoline. May specify multiple users as
465
365
            ivle_install_dir = opts['--ivle_install_dir']
466
366
        if '--jail_base' in opts:
467
367
            jail_base = opts['--jail_base']
468
 
        if '--subjects_base' in opts:
469
 
            jail_base = opts['--subjects_base']
470
 
        if '--public_host' in opts:
471
 
            public_host = opts['--public_host']
472
368
        if '--allowed_uids' in opts:
473
369
            allowed_uids = opts['--allowed_uids']
474
370
 
500
396
# This directory should contain the "www" and "bin" directories.
501
397
ivle_install_dir = "%s"
502
398
 
503
 
# The server goes into "public mode" if the browser sends a request with this
504
 
# host. This is for security reasons - we only serve public student files on a
505
 
# separate domain to the main IVLE site.
506
 
# Public mode does not use cookies, and serves only public content.
507
 
# Private mode (normal mode) requires login, and only serves files relevant to
508
 
# the logged-in user.
509
 
public_host = "%s"
510
 
 
511
399
# In the local file system, where are the student/user file spaces located.
512
400
# The user jails are expected to be located immediately in subdirectories of
513
401
# this location.
514
402
jail_base = "%s"
515
 
 
516
 
# In the local file system, where are the per-subject file spaces located.
517
 
# The individual subject directories are expected to be located immediately
518
 
# in subdirectories of this location.
519
 
subjects_base = "%s"
520
 
""" % (root_dir, ivle_install_dir, public_host, jail_base, subjects_base))
 
403
""" % (root_dir, ivle_install_dir, jail_base))
521
404
 
522
405
        conf.close()
523
406
    except IOError, (errno, strerror):
587
470
    # Copy all console and operating system files into the jail
588
471
    action_copylist(install_list.list_console, 'jail/opt/ivle', dry)
589
472
    copy_os_files_jail(dry)
590
 
    # Chmod the python console
591
 
    action_chmod_x('jail/opt/ivle/console/python-console', dry)
592
 
    
593
473
 
594
474
    # Compile .py files into .pyc or .pyo files
595
475
    compileall.compile_dir('www', quiet=True)
601
481
    """Copies necessary Operating System files from their usual locations
602
482
    into the jail/ directory of the cwd."""
603
483
    # Currently source paths are configured for Ubuntu.
604
 
    for filename in JAIL_FILES:
605
 
        copy_file_to_jail(filename, dry)
606
 
    for src, dst in JAIL_LINKS.items():
607
 
        action_symlink(src, dst, dry)
608
 
    for src, dst in JAIL_COPYTREES.items():
609
 
        action_copytree(src, dst, dry)
 
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)
610
493
 
611
494
def copy_file_to_jail(src, dry):
612
495
    """Copies a single file from an absolute location into the same location
616
499
 
617
500
def install(args):
618
501
    # Get "dry" and "nojail" variables from command line
619
 
    (opts, args) = getopt.gnu_getopt(args, "n",
620
 
        ['dry', 'nojail', 'nosubjects'])
 
502
    (opts, args) = getopt.gnu_getopt(args, "n", ['dry', 'nojail'])
621
503
    opts = dict(opts)
622
504
    dry = '-n' in opts or '--dry' in opts
623
505
    nojail = '--nojail' in opts
624
 
    nosubjects = '--nosubjects' in opts
625
506
 
626
507
    if dry:
627
508
        print "Dry run (no actions will be executed\n"
649
530
        # to the jails template directory (it will be used as a template
650
531
        # for all the students' jails).
651
532
        action_copytree('jail', os.path.join(jail_base, 'template'), dry)
652
 
    if not nosubjects:
653
 
        # Copy the subjects directory across
654
 
        action_copylist(install_list.list_subjects, subjects_base, dry,
655
 
            srcdir="./subjects")
656
 
 
657
 
    # Append IVLE path to ivle.pth in python site packages
658
 
    # (Unless it's already there)
659
 
    ivle_pth = os.path.join(sys.prefix,
660
 
        "lib/python2.5/site-packages/ivle.pth")
661
 
    ivle_www = os.path.join(ivle_install_dir, "www")
662
 
    write_ivle_pth = True
663
 
    try:
664
 
        file = open(ivle_pth, 'r')
665
 
        for line in file:
666
 
            if line.strip() == ivle_www:
667
 
                write_ivle_pth = False
668
 
                break
669
 
    except (IOError, OSError):
670
 
        pass
671
 
    if write_ivle_pth:
672
 
        action_append(ivle_pth, ivle_www)
673
 
 
674
 
    return 0
675
 
 
676
 
def updatejails(args):
677
 
    # Get "dry" variable from command line
678
 
    (opts, args) = getopt.gnu_getopt(args, "n", ['dry'])
679
 
    opts = dict(opts)
680
 
    dry = '-n' in opts or '--dry' in opts
681
 
 
682
 
    if dry:
683
 
        print "Dry run (no actions will be executed\n"
684
 
 
685
 
    if not dry and os.geteuid() != 0:
686
 
        print >>sys.stderr, "Must be root to run install"
687
 
        print >>sys.stderr, "(I need to chown some files)."
688
 
        return 1
689
 
 
690
 
    # Update the template jail directory in case it hasn't been installed
691
 
    # recently.
692
 
    action_copytree('jail', os.path.join(jail_base, 'template'), dry)
693
 
 
694
 
    # Re-link all the files in all students jails.
695
 
    for dir in os.listdir(jail_base):
696
 
        if dir == 'template': continue
697
 
        # First back up the student's home directory
698
 
        temp_home = os.tmpnam()
699
 
        action_rename(os.path.join(jail_base, dir, 'home'), temp_home, dry)
700
 
        # Delete the student's jail and relink the jail files
701
 
        action_linktree(os.path.join(jail_base, 'template'),
702
 
            os.path.join(jail_base, dir), dry)
703
 
        # Restore the student's home directory
704
 
        action_rename(temp_home, os.path.join(jail_base, dir, 'home'), dry)
705
 
        # Set up the user's home directory just in case they don't have a
706
 
        # directory for this yet
707
 
        action_mkdir(os.path.join(jail_base, dir, 'home', dir), dry)
708
533
 
709
534
    return 0
710
535
 
737
562
    if ret != 0:
738
563
        raise RunError(prog, ret)
739
564
 
740
 
def action_rename(src, dst, dry):
741
 
    """Calls rename. Deletes the target if it already exists."""
742
 
    if os.access(dst, os.F_OK):
743
 
        print "rm -r", dst
744
 
        if not dry:
745
 
            shutil.rmtree(dst, True)
746
 
    print "mv ", src, dst
747
 
    if dry: return
748
 
    try:
749
 
        os.rename(src, dst)
750
 
    except OSError, (err, msg):
751
 
        if err != errno.EEXIST:
752
 
            raise
753
 
 
754
565
def action_mkdir(path, dry):
755
566
    """Calls mkdir. Silently ignored if the directory already exists.
756
567
    Creates all parent directories as necessary."""
776
587
    if dry: return
777
588
    shutil.copytree(src, dst, True)
778
589
 
779
 
def action_linktree(src, dst, dry):
780
 
    """Hard-links an entire directory tree. Same as copytree but the created
781
 
    files are hard-links not actual copies. Removes the existing destination.
782
 
    """
783
 
    if os.access(dst, os.F_OK):
784
 
        print "rm -r", dst
785
 
        if not dry:
786
 
            shutil.rmtree(dst, True)
787
 
    print "<cp with hardlinks> -r", src, dst
788
 
    if dry: return
789
 
    common.makeuser.linktree(src, dst)
790
 
 
791
 
def action_copylist(srclist, dst, dry, srcdir="."):
 
590
def action_copylist(srclist, dst, dry):
792
591
    """Copies all files in a list to a new location. The files in the list
793
592
    are read relative to the current directory, and their destinations are the
794
593
    same paths relative to dst. Creates all parent directories as necessary.
795
 
    srcdir is "." by default, can be overridden.
796
594
    """
797
595
    for srcfile in srclist:
798
596
        dstfile = os.path.join(dst, srcfile)
799
 
        srcfile = os.path.join(srcdir, srcfile)
800
597
        dstdir = os.path.split(dstfile)[0]
801
598
        if not os.path.isdir(dstdir):
802
599
            action_mkdir(dstdir, dry)
837
634
    if not dry:
838
635
        os.symlink(src, dst)
839
636
 
840
 
def action_append(ivle_pth, ivle_www):
841
 
    file = open(ivle_pth, 'a+')
842
 
    file.write(ivle_www + '\n')
843
 
    file.close()
844
 
 
845
637
def action_chown_setuid(file, dry):
846
638
    """Chowns a file to root, and sets the setuid bit on the file.
847
639
    Calling this function requires the euid to be root.
856
648
        os.chmod(file, stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
857
649
            | stat.S_ISUID | stat.S_IRUSR | stat.S_IWUSR)
858
650
 
859
 
def action_chmod_x(file, dry):
860
 
    """Chmod +xs a file (sets execute permission)."""
861
 
    print "chmod u+rwx", file
862
 
    if not dry:
863
 
        os.chmod(file, stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR)
864
 
 
865
651
def query_user(default, prompt):
866
652
    """Prompts the user for a string, which is read from a line of stdin.
867
653
    Exits silently if EOF is encountered. Returns the string, with spaces