| Justin Shepherd | 0d9bbd1 | 2011-08-11 12:57:44 -0500 | [diff] [blame^] | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | 
|  | 2 |  | 
|  | 3 | """ | 
|  | 4 | Installation script for Kong's testing virtualenv | 
|  | 5 | """ | 
|  | 6 |  | 
|  | 7 | import os | 
|  | 8 | import stat | 
|  | 9 | import string | 
|  | 10 | import subprocess | 
|  | 11 | import sys | 
|  | 12 |  | 
|  | 13 | ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) | 
|  | 14 | VENV = os.path.join(ROOT, '.kong-venv') | 
|  | 15 | PIP_REQUIRES = os.path.join(ROOT, 'tools', 'pip-requires') | 
|  | 16 |  | 
|  | 17 |  | 
|  | 18 | def die(message, *args): | 
|  | 19 | print >> sys.stderr, message % args | 
|  | 20 | sys.exit(1) | 
|  | 21 |  | 
|  | 22 |  | 
|  | 23 | def whereis(executable): | 
|  | 24 | """ | 
|  | 25 | Detect whereis a binary and make sure it's executable we can execute. | 
|  | 26 | """ | 
|  | 27 | for d in string.split(os.environ['PATH'], \ | 
|  | 28 | os.pathsep): | 
|  | 29 | f = os.path.join(d, executable) | 
|  | 30 | if os.path.isfile(f): | 
|  | 31 | try: | 
|  | 32 | st = os.stat(f) | 
|  | 33 | except OSError: | 
|  | 34 | continue | 
|  | 35 | if stat.S_IMODE(st[stat.ST_MODE]) & 0111: | 
|  | 36 | return True | 
|  | 37 | return False | 
|  | 38 |  | 
|  | 39 |  | 
|  | 40 | def run_command(cmd, redirect_output=True, check_exit_code=True): | 
|  | 41 | """ | 
|  | 42 | Runs a command in an out-of-process shell, returning the | 
|  | 43 | output of that command.  Working directory is ROOT. | 
|  | 44 | """ | 
|  | 45 | if redirect_output: | 
|  | 46 | stdout = subprocess.PIPE | 
|  | 47 | else: | 
|  | 48 | stdout = None | 
|  | 49 |  | 
|  | 50 | proc = subprocess.Popen(cmd, cwd=ROOT, stdout=stdout) | 
|  | 51 | output = proc.communicate()[0] | 
|  | 52 | if check_exit_code and proc.returncode != 0: | 
|  | 53 | die('Command "%s" failed.\n%s', ' '.join(cmd), output) | 
|  | 54 | return output | 
|  | 55 |  | 
|  | 56 |  | 
|  | 57 | HAS_EASY_INSTALL = bool(whereis("easy_install")) | 
|  | 58 | HAS_VIRTUALENV = bool(whereis("virtualenv")) | 
|  | 59 |  | 
|  | 60 |  | 
|  | 61 | def check_dependencies(): | 
|  | 62 | """Make sure virtualenv is in the path.""" | 
|  | 63 |  | 
|  | 64 | if not HAS_VIRTUALENV: | 
|  | 65 | print 'not found.' | 
|  | 66 | # Try installing it via easy_install... | 
|  | 67 | if HAS_EASY_INSTALL: | 
|  | 68 | print 'Installing virtualenv via easy_install...', | 
|  | 69 | if not run_command(['easy_install', 'virtualenv']): | 
|  | 70 | die('ERROR: virtualenv not found.\n\n' | 
|  | 71 | 'Glance development requires virtualenv, please install' | 
|  | 72 | ' it using your favorite package management tool') | 
|  | 73 | print 'done.' | 
|  | 74 | print 'done.' | 
|  | 75 |  | 
|  | 76 |  | 
|  | 77 | def create_virtualenv(venv=VENV): | 
|  | 78 | """Creates the virtual environment and installs PIP only into the | 
|  | 79 | virtual environment | 
|  | 80 | """ | 
|  | 81 | print 'Creating venv...', | 
|  | 82 | run_command(['virtualenv', '-q', '--no-site-packages', VENV]) | 
|  | 83 | print 'done.' | 
|  | 84 | print 'Installing pip in virtualenv...', | 
|  | 85 | if not run_command(['tools/with_venv.sh', 'easy_install', 'pip']).strip(): | 
|  | 86 | die("Failed to install pip.") | 
|  | 87 | print 'done.' | 
|  | 88 |  | 
|  | 89 |  | 
|  | 90 | def install_dependencies(venv=VENV): | 
|  | 91 | print 'Installing dependencies with pip (this can take a while)...' | 
|  | 92 |  | 
|  | 93 | # Install greenlet by hand - just listing it in the requires file does not | 
|  | 94 | # get it in stalled in the right order | 
|  | 95 | venv_tool = 'tools/with_venv.sh' | 
|  | 96 | run_command([venv_tool, 'pip', 'install', '-E', venv, '-r', PIP_REQUIRES], | 
|  | 97 | redirect_output=False) | 
|  | 98 |  | 
|  | 99 | # Tell the virtual env how to "import glance" | 
|  | 100 | pthfile = os.path.join(venv, "lib", "python2.6", "site-packages", | 
|  | 101 | "glance.pth") | 
|  | 102 | f = open(pthfile, 'w') | 
|  | 103 | f.write("%s\n" % ROOT) | 
|  | 104 |  | 
|  | 105 |  | 
|  | 106 | def print_help(): | 
|  | 107 | help = """ | 
|  | 108 | Kong testing environment setup is complete. | 
|  | 109 |  | 
|  | 110 | Kong testing uses virtualenv to track and manage Python dependencies | 
|  | 111 | while in development and testing. | 
|  | 112 |  | 
|  | 113 | To activate the Kong virtualenv for the extent of your current shell | 
|  | 114 | session you can run: | 
|  | 115 |  | 
|  | 116 | $ source .kong-venv/bin/activate | 
|  | 117 |  | 
|  | 118 | Or, if you prefer, you can run commands in the virtualenv on a case by case | 
|  | 119 | basis by running: | 
|  | 120 |  | 
|  | 121 | $ tools/with_venv.sh <your command> | 
|  | 122 |  | 
|  | 123 | Also, make test will automatically use the virtualenv. | 
|  | 124 | """ | 
|  | 125 | print help | 
|  | 126 |  | 
|  | 127 |  | 
|  | 128 | def main(argv): | 
|  | 129 | check_dependencies() | 
|  | 130 | create_virtualenv() | 
|  | 131 | install_dependencies() | 
|  | 132 | print_help() | 
|  | 133 |  | 
|  | 134 | if __name__ == '__main__': | 
|  | 135 | main(sys.argv) |