blob: 1bab88a3fd3ccecabb0b53c52f321ac33430869b [file] [log] [blame]
Matthew Treinish51dfee72013-01-28 15:50:29 -05001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
Dirk Mueller74af42c2013-06-23 20:50:22 +02003# Copyright 2013 OpenStack Foundation
Matthew Treinish51dfee72013-01-28 15:50:29 -05004# Copyright 2013 IBM Corp.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18"""Provides methods needed by installation script for OpenStack development
19virtual environments.
20
Dirk Mueller74af42c2013-06-23 20:50:22 +020021Since this script is used to bootstrap a virtualenv from the system's Python
22environment, it should be kept strictly compatible with Python 2.6.
23
Matthew Treinish51dfee72013-01-28 15:50:29 -050024Synced in from openstack-common
25"""
26
Dirk Mueller74af42c2013-06-23 20:50:22 +020027from __future__ import print_function
28
29import optparse
Matthew Treinish51dfee72013-01-28 15:50:29 -050030import os
31import subprocess
32import sys
33
Matthew Treinish7682cde2013-02-06 16:34:40 -050034
Matthew Treinish51dfee72013-01-28 15:50:29 -050035class InstallVenv(object):
36
Monty Taylor7a3c3792013-07-05 22:15:06 -040037 def __init__(self, root, venv, requirements,
38 test_requirements, py_version,
Matthew Treinish51dfee72013-01-28 15:50:29 -050039 project):
40 self.root = root
41 self.venv = venv
Monty Taylor7a3c3792013-07-05 22:15:06 -040042 self.requirements = requirements
43 self.test_requirements = test_requirements
Matthew Treinish51dfee72013-01-28 15:50:29 -050044 self.py_version = py_version
45 self.project = project
46
47 def die(self, message, *args):
Dirk Mueller74af42c2013-06-23 20:50:22 +020048 print(message % args, file=sys.stderr)
Matthew Treinish51dfee72013-01-28 15:50:29 -050049 sys.exit(1)
50
51 def check_python_version(self):
52 if sys.version_info < (2, 6):
53 self.die("Need Python Version >= 2.6")
54
55 def run_command_with_code(self, cmd, redirect_output=True,
56 check_exit_code=True):
57 """Runs a command in an out-of-process shell.
58
Joe Gordon2b0591d2013-02-14 23:18:39 +000059 Returns the output of that command. Working directory is self.root.
Matthew Treinish51dfee72013-01-28 15:50:29 -050060 """
61 if redirect_output:
62 stdout = subprocess.PIPE
63 else:
64 stdout = None
65
66 proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout)
67 output = proc.communicate()[0]
68 if check_exit_code and proc.returncode != 0:
69 self.die('Command "%s" failed.\n%s', ' '.join(cmd), output)
70 return (output, proc.returncode)
71
72 def run_command(self, cmd, redirect_output=True, check_exit_code=True):
73 return self.run_command_with_code(cmd, redirect_output,
74 check_exit_code)[0]
75
76 def get_distro(self):
77 if (os.path.exists('/etc/fedora-release') or
78 os.path.exists('/etc/redhat-release')):
Monty Taylor7a3c3792013-07-05 22:15:06 -040079 return Fedora(
80 self.root, self.venv, self.requirements,
81 self.test_requirements, self.py_version, self.project)
Matthew Treinish51dfee72013-01-28 15:50:29 -050082 else:
Monty Taylor7a3c3792013-07-05 22:15:06 -040083 return Distro(
84 self.root, self.venv, self.requirements,
85 self.test_requirements, self.py_version, self.project)
Matthew Treinish51dfee72013-01-28 15:50:29 -050086
87 def check_dependencies(self):
88 self.get_distro().install_virtualenv()
89
90 def create_virtualenv(self, no_site_packages=True):
91 """Creates the virtual environment and installs PIP.
92
93 Creates the virtual environment and installs PIP only into the
94 virtual environment.
95 """
96 if not os.path.isdir(self.venv):
Dirk Mueller74af42c2013-06-23 20:50:22 +020097 print('Creating venv...', end=' ')
Matthew Treinish51dfee72013-01-28 15:50:29 -050098 if no_site_packages:
99 self.run_command(['virtualenv', '-q', '--no-site-packages',
100 self.venv])
101 else:
102 self.run_command(['virtualenv', '-q', self.venv])
Dirk Mueller74af42c2013-06-23 20:50:22 +0200103 print('done.')
Matthew Treinish51dfee72013-01-28 15:50:29 -0500104 else:
Dirk Mueller74af42c2013-06-23 20:50:22 +0200105 print("venv already exists...")
Matthew Treinish51dfee72013-01-28 15:50:29 -0500106 pass
107
108 def pip_install(self, *args):
109 self.run_command(['tools/with_venv.sh',
110 'pip', 'install', '--upgrade'] + list(args),
111 redirect_output=False)
112
113 def install_dependencies(self):
Dirk Mueller74af42c2013-06-23 20:50:22 +0200114 print('Installing dependencies with pip (this can take a while)...')
Matthew Treinish51dfee72013-01-28 15:50:29 -0500115
116 # First things first, make sure our venv has the latest pip and
Matthew Treinishffa94d62013-09-11 18:09:17 +0000117 # setuptools and pbr
118 self.pip_install('pip>=1.4')
Monty Taylor7a3c3792013-07-05 22:15:06 -0400119 self.pip_install('setuptools')
Matthew Treinishffa94d62013-09-11 18:09:17 +0000120 self.pip_install('pbr')
Matthew Treinish51dfee72013-01-28 15:50:29 -0500121
Matthew Treinish50bf2d22013-09-20 11:54:32 -0400122 self.pip_install('-r', self.requirements, '-r', self.test_requirements)
Matthew Treinish51dfee72013-01-28 15:50:29 -0500123
Matthew Treinish51dfee72013-01-28 15:50:29 -0500124 def parse_args(self, argv):
125 """Parses command-line arguments."""
Dirk Mueller74af42c2013-06-23 20:50:22 +0200126 parser = optparse.OptionParser()
127 parser.add_option('-n', '--no-site-packages',
128 action='store_true',
129 help="Do not inherit packages from global Python "
130 "install")
131 return parser.parse_args(argv[1:])[0]
Matthew Treinish51dfee72013-01-28 15:50:29 -0500132
133
134class Distro(InstallVenv):
135
136 def check_cmd(self, cmd):
137 return bool(self.run_command(['which', cmd],
138 check_exit_code=False).strip())
139
140 def install_virtualenv(self):
141 if self.check_cmd('virtualenv'):
142 return
143
144 if self.check_cmd('easy_install'):
Dirk Mueller74af42c2013-06-23 20:50:22 +0200145 print('Installing virtualenv via easy_install...', end=' ')
Matthew Treinish51dfee72013-01-28 15:50:29 -0500146 if self.run_command(['easy_install', 'virtualenv']):
Dirk Mueller74af42c2013-06-23 20:50:22 +0200147 print('Succeeded')
Matthew Treinish51dfee72013-01-28 15:50:29 -0500148 return
149 else:
Dirk Mueller74af42c2013-06-23 20:50:22 +0200150 print('Failed')
Matthew Treinish51dfee72013-01-28 15:50:29 -0500151
152 self.die('ERROR: virtualenv not found.\n\n%s development'
153 ' requires virtualenv, please install it using your'
154 ' favorite package management tool' % self.project)
155
Matthew Treinish51dfee72013-01-28 15:50:29 -0500156
157class Fedora(Distro):
158 """This covers all Fedora-based distributions.
159
160 Includes: Fedora, RHEL, CentOS, Scientific Linux
161 """
162
163 def check_pkg(self, pkg):
164 return self.run_command_with_code(['rpm', '-q', pkg],
165 check_exit_code=False)[1] == 0
166
Matthew Treinish51dfee72013-01-28 15:50:29 -0500167 def install_virtualenv(self):
168 if self.check_cmd('virtualenv'):
169 return
170
171 if not self.check_pkg('python-virtualenv'):
Dirk Mueller74af42c2013-06-23 20:50:22 +0200172 self.die("Please install 'python-virtualenv'.")
Matthew Treinish51dfee72013-01-28 15:50:29 -0500173
174 super(Fedora, self).install_virtualenv()