0
|
1 |
#
|
|
2 |
# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
# All rights reserved.
|
|
4 |
# This component and the accompanying materials are made available
|
|
5 |
# under the terms of "Eclipse Public License v1.0"
|
|
6 |
# which accompanies this distribution, and is available
|
|
7 |
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
#
|
|
9 |
# Initial Contributors:
|
|
10 |
# Nokia Corporation - initial contribution.
|
|
11 |
#
|
|
12 |
# Contributors:
|
|
13 |
#
|
|
14 |
# Description:
|
|
15 |
# Script for building and installing ConE into a specified directory.
|
|
16 |
#
|
|
17 |
|
|
18 |
import sys, os, shutil, subprocess, optparse
|
|
19 |
import logging
|
|
20 |
log = logging.getLogger()
|
|
21 |
|
|
22 |
import utils
|
|
23 |
utils.setup_logging('install_cone.log')
|
|
24 |
|
|
25 |
ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
|
|
26 |
|
3
|
27 |
# The sub-directory of the main install directory where all required libraries
|
|
28 |
# etc. are installed
|
|
29 |
INSTALL_SUBDIR = 'configurationengine'
|
|
30 |
|
|
31 |
# The sub-directory for required libraries, platform-specific
|
|
32 |
if sys.platform == "win32":
|
|
33 |
PLATFORM_SUBDIR = 'win'
|
|
34 |
else:
|
|
35 |
PLATFORM_SUBDIR = 'linux'
|
|
36 |
|
|
37 |
PYTHON_EXECUTABLE = 'python'
|
|
38 |
|
0
|
39 |
SOURCE_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '../source'))
|
|
40 |
assert os.path.isdir(SOURCE_ROOT)
|
|
41 |
SCRIPTS_SOURCE_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '../source/scripts'))
|
|
42 |
assert os.path.isdir(SCRIPTS_SOURCE_ROOT)
|
|
43 |
PLUGIN_SOURCE_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '../source/plugins'))
|
|
44 |
assert os.path.isdir(PLUGIN_SOURCE_ROOT)
|
3
|
45 |
TESTAUTOMATION_ROOT = os.path.abspath(os.path.join(SOURCE_ROOT, 'testautomation'))
|
|
46 |
assert os.path.isdir(TESTAUTOMATION_ROOT)
|
0
|
47 |
|
3
|
48 |
sys.path.insert(0, TESTAUTOMATION_ROOT)
|
0
|
49 |
sys.path.append(PLUGIN_SOURCE_ROOT)
|
3
|
50 |
from testautomation import plugin_utils
|
0
|
51 |
|
|
52 |
# Temporary directory where ConE eggs are built into
|
|
53 |
TEMP_CONE_EGG_DIR = os.path.join(ROOT_PATH, 'install-temp/cone-eggs')
|
|
54 |
# Temporary directory where dependency lib eggs are copied
|
|
55 |
TEMP_LIB_EGG_DIR = os.path.join(ROOT_PATH, 'install-temp/dep-eggs')
|
|
56 |
|
|
57 |
class BuildFailedError(RuntimeError):
|
|
58 |
pass
|
|
59 |
|
|
60 |
def find_cone_egg_sources(plugin_package):
|
|
61 |
"""
|
|
62 |
Return a list of paths to the source directories to install.
|
|
63 |
"""
|
|
64 |
paths = [SOURCE_ROOT,
|
|
65 |
SCRIPTS_SOURCE_ROOT]
|
3
|
66 |
plugin_paths = plugin_utils.find_plugin_sources_by_package(PLUGIN_SOURCE_ROOT, plugin_package)
|
0
|
67 |
paths.extend(plugin_paths)
|
|
68 |
|
|
69 |
log.debug("ConE egg source paths:\n%s" % '\n'.join(paths))
|
|
70 |
return paths
|
|
71 |
|
|
72 |
|
3
|
73 |
def build_cone_eggs(source_paths, python_executable):
|
0
|
74 |
log.info("Cleaning temporary ConE egg dir...")
|
|
75 |
utils.recreate_dir(TEMP_CONE_EGG_DIR)
|
|
76 |
|
|
77 |
log.info("Building ConE eggs...")
|
|
78 |
for source_path in source_paths:
|
3
|
79 |
ok = utils.build_egg(source_path, TEMP_CONE_EGG_DIR, python_executable)
|
0
|
80 |
if not ok:
|
|
81 |
raise BuildFailedError()
|
|
82 |
|
|
83 |
def retrieve_dep_eggs(plugin_package):
|
|
84 |
log.info("Cleaning temporary lib egg dir...")
|
|
85 |
utils.recreate_dir(TEMP_LIB_EGG_DIR)
|
|
86 |
|
|
87 |
log.info("Retrieving dependency eggs...")
|
|
88 |
def copy_eggs(source_dir):
|
|
89 |
log.debug("Copying eggs from '%s'..." % source_dir)
|
|
90 |
for name in os.listdir(source_dir):
|
|
91 |
if name.endswith('.egg'):
|
3
|
92 |
if PLATFORM_SUBDIR == 'linux' and name.startswith('setuptools-0.6c11'):
|
|
93 |
continue
|
|
94 |
else:
|
|
95 |
utils.copy_file(
|
|
96 |
source_path = os.path.join(source_dir, name),
|
|
97 |
target_path = TEMP_LIB_EGG_DIR)
|
0
|
98 |
|
|
99 |
dep_dirs_by_package = [(None, os.path.join(ROOT_PATH, '../dep-eggs'))]
|
3
|
100 |
dep_dirs_by_package.extend(plugin_utils.find_plugin_package_subpaths(PLUGIN_SOURCE_ROOT, 'dep-eggs', plugin_package))
|
0
|
101 |
|
|
102 |
for package_name, dep_dir in dep_dirs_by_package:
|
|
103 |
copy_eggs(dep_dir)
|
|
104 |
|
|
105 |
def init_target_dir(target_dir, python_version):
|
3
|
106 |
BASE_DIR = os.path.normpath(os.path.join(target_dir, INSTALL_SUBDIR, PLATFORM_SUBDIR, python_version))
|
0
|
107 |
LIB_DIR = os.path.join(BASE_DIR, 'lib')
|
|
108 |
SCRIPT_DIR = os.path.join(BASE_DIR, 'scripts')
|
|
109 |
|
|
110 |
utils.recreate_dir(BASE_DIR)
|
|
111 |
utils.recreate_dir(LIB_DIR)
|
|
112 |
utils.recreate_dir(SCRIPT_DIR)
|
|
113 |
return LIB_DIR, SCRIPT_DIR
|
|
114 |
|
|
115 |
def install_cone_eggs(target_dir, python_version):
|
|
116 |
"""
|
|
117 |
Install ConE eggs into the given target directory.
|
|
118 |
"""
|
|
119 |
log.info("Installing ConE eggs...")
|
|
120 |
LIB_DIR, SCRIPT_DIR = init_target_dir(target_dir, python_version)
|
|
121 |
|
|
122 |
# Collect the eggs to install
|
3
|
123 |
eggs = ['setuptools'] # Setuptools are needed
|
|
124 |
|
0
|
125 |
for name in os.listdir(TEMP_CONE_EGG_DIR):
|
|
126 |
if name.endswith('.egg'):
|
|
127 |
eggs.append(TEMP_CONE_EGG_DIR + '/' + name)
|
|
128 |
|
|
129 |
# Run easy_install to install the eggs
|
|
130 |
for egg in eggs:
|
|
131 |
log.debug(egg)
|
|
132 |
|
5
|
133 |
command = ['easy_install-%s' % python_version,
|
|
134 |
'--find-links install-temp/dep-eggs',
|
|
135 |
'--install-dir "%s"' % LIB_DIR,
|
|
136 |
'--script-dir "%s"' % SCRIPT_DIR,
|
|
137 |
'--site-dirs "%s"' % LIB_DIR,
|
|
138 |
'--always-unzip']
|
|
139 |
|
|
140 |
if PLATFORM_SUBDIR == 'win':
|
|
141 |
# Use --always-copy on Windows to copy all needed libraries
|
|
142 |
command.append('--always-copy')
|
|
143 |
|
0
|
144 |
command.append('"' + egg + '"')
|
|
145 |
command = ' '.join(command)
|
|
146 |
|
|
147 |
log.debug(command)
|
|
148 |
ok = utils.run_command(command, env_overrides={'PYTHONPATH': LIB_DIR})
|
|
149 |
if not ok:
|
|
150 |
raise BuildFailedError()
|
|
151 |
|
3
|
152 |
def develop_install_cone_sources(source_paths, target_dir, python_version, python_executable):
|
0
|
153 |
log.info("Installing ConE sources in develop mode...")
|
|
154 |
LIB_DIR, SCRIPT_DIR = init_target_dir(target_dir, python_version)
|
|
155 |
|
|
156 |
orig_workdir = os.getcwd()
|
|
157 |
try:
|
|
158 |
for source_path in source_paths:
|
|
159 |
os.chdir(source_path)
|
3
|
160 |
command = ['%s setup.py develop' % python_executable,
|
0
|
161 |
'--find-links "%s"' % os.path.normpath(os.path.join(ROOT_PATH, 'install-temp/dep-eggs')),
|
|
162 |
'--install-dir "%s"' % LIB_DIR,
|
|
163 |
'--script-dir "%s"' % SCRIPT_DIR,
|
|
164 |
'--site-dirs "%s"' % LIB_DIR,
|
5
|
165 |
]
|
0
|
166 |
command = ' '.join(command)
|
|
167 |
log.debug(command)
|
|
168 |
ok = utils.run_command(command, env_overrides={'PYTHONPATH': LIB_DIR})
|
|
169 |
if not ok:
|
|
170 |
raise BuildFailedError()
|
|
171 |
finally:
|
|
172 |
os.chdir(orig_workdir)
|
|
173 |
|
3
|
174 |
def perform_build(target_dir, plugin_package, install_type, python_version, python_executable):
|
|
175 |
log.info("Target directory: %s" % target_dir)
|
|
176 |
log.info("Plug-in package: %r" % plugin_package)
|
|
177 |
log.info("Python version: %s" % python_version)
|
|
178 |
log.info("Python executable: %s" % python_executable)
|
0
|
179 |
|
|
180 |
# Retrieve dependencies to the correct location
|
|
181 |
retrieve_dep_eggs(plugin_package)
|
|
182 |
|
5
|
183 |
# Install the dependencies locally using either local copies or downloading from PyPi
|
|
184 |
deps = ['Jinja2', 'lxml']
|
|
185 |
for dep in deps:
|
|
186 |
command = ['easy_install-%s' % python_version,
|
|
187 |
'--find-links install-temp/dep-eggs']
|
|
188 |
|
|
189 |
command.append(dep)
|
|
190 |
command = ' '.join(command)
|
|
191 |
log.debug(command)
|
|
192 |
ok = utils.run_command(command)
|
|
193 |
if not ok:
|
|
194 |
print "Warning: failed to run easy_install to install %s." % dep
|
|
195 |
|
|
196 |
|
|
197 |
|
0
|
198 |
# Find paths to the sources to install
|
|
199 |
source_paths = find_cone_egg_sources(plugin_package)
|
|
200 |
|
|
201 |
log.info("Creating install directory...")
|
|
202 |
if not os.path.exists(target_dir):
|
|
203 |
os.makedirs(target_dir)
|
|
204 |
|
3
|
205 |
if install_type == 'build':
|
|
206 |
build_cone_eggs(source_paths, python_executable)
|
0
|
207 |
if install_type == 'install':
|
3
|
208 |
build_cone_eggs(source_paths, python_executable)
|
0
|
209 |
install_cone_eggs(target_dir, python_version)
|
|
210 |
else:
|
3
|
211 |
develop_install_cone_sources(source_paths, target_dir, python_version, python_executable)
|
0
|
212 |
|
|
213 |
# Copy RELEASE.txt
|
|
214 |
utils.copy_file(
|
|
215 |
source_path = os.path.join(SOURCE_ROOT, '..', 'RELEASE.TXT'),
|
3
|
216 |
target_path = os.path.join(target_dir, INSTALL_SUBDIR, 'RELEASE.TXT'))
|
0
|
217 |
|
|
218 |
# Copy cone.cmd or cone.sh, depending on the platform
|
|
219 |
if sys.platform == "win32":
|
3
|
220 |
sourcefile = targetfile = "cone.cmd"
|
0
|
221 |
else:
|
3
|
222 |
sourcefile = "cone.sh"
|
|
223 |
targetfile = "cone"
|
|
224 |
log.info("Copying %s" % sourcefile)
|
0
|
225 |
utils.copy_file(
|
3
|
226 |
source_path = os.path.join(SOURCE_ROOT, sourcefile),
|
|
227 |
target_path = os.path.join(target_dir, targetfile))
|
0
|
228 |
|
|
229 |
def main():
|
|
230 |
parser = optparse.OptionParser()
|
|
231 |
parser.add_option("-t", "--target-dir",
|
|
232 |
help="The directory where ConE is to be installed.")
|
|
233 |
parser.add_option("-p", "--plugin-package",\
|
|
234 |
help="The plug-in package to include in the installation.",\
|
|
235 |
default=None)
|
|
236 |
parser.add_option("-i", "--install-type",\
|
|
237 |
help="The installation type, can be 'install' (the default) or 'develop'.",\
|
|
238 |
default='install')
|
3
|
239 |
parser.add_option("--python-executable",\
|
|
240 |
help="The Python executable to run type, defaults to 'python'.",\
|
|
241 |
default='python')
|
0
|
242 |
(options, args) = parser.parse_args()
|
|
243 |
if options.target_dir is None:
|
|
244 |
parser.error("Target directory must be given")
|
3
|
245 |
if options.install_type not in ('install', 'build', 'develop'):
|
0
|
246 |
parser.error("Invalid install type ('%s')" % options.install_type)
|
3
|
247 |
|
|
248 |
if not utils.run_command("%s --help" % options.python_executable):
|
|
249 |
log.critical("Could not run '%s'. Please make sure that you "\
|
|
250 |
"have Python installed and in your path." % options.python_executable)
|
0
|
251 |
return 1
|
|
252 |
|
3
|
253 |
python_version = utils.get_python_version(options.python_executable)
|
|
254 |
|
|
255 |
easy_install_cmd = "easy_install-%s" % python_version
|
|
256 |
if not utils.run_command("%s --help" % easy_install_cmd):
|
|
257 |
log.critical("Could not run '%s'. Please make sure that you "\
|
|
258 |
"have setuptools installed and the Python scripts directory in your path."\
|
|
259 |
% easy_install_cmd)
|
0
|
260 |
return 1
|
|
261 |
|
3
|
262 |
|
0
|
263 |
|
|
264 |
try:
|
3
|
265 |
perform_build(options.target_dir, options.plugin_package, options.install_type, python_version, options.python_executable)
|
0
|
266 |
except BuildFailedError:
|
|
267 |
return 1
|
|
268 |
|
|
269 |
return 0
|
|
270 |
|
|
271 |
if __name__ == "__main__":
|
|
272 |
sys.exit(main())
|