1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
#=====================================================
# Copyright (C) 2011 Andrea Arteaga <andyspiros@gmail.com>
#=====================================================
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
import commands as cmd
import subprocess as sp
import os, portage, shlex
from os.path import join as pjoin, dirname
import benchutils
class InstallException(Exception):
def __init__(self, package, command, logfile):
self.package = package
self.command = command
self.logfile = logfile
def _getEnv(root='/', envAdds={}):
#denv = os.environ.copy()
denv = {}
#PATH
denv['PATH'] = ':'.join([pjoin(root, i) for i in ('bin', 'usr/bin')])
if os.environ.has_key('PATH'):
denv['PATH'] += ':' + os.environ['PATH']
denv['ROOTPATH'] = denv['PATH']
#LIBRARY_PATH
denv['LIBRARY_PATH'] = ':'.join([pjoin(root, i) for i in \
('usr/lib', 'usr/lib64', 'usr/lib32')])
if os.environ.has_key('LIBRARY_PATH'):
denv['LIBRARY_PATH'] += ':' + os.environ['LIBRARY_PATH']
#LD_LIBRARY_PATH
denv['LD_LIBRARY_PATH'] = ':'.join([pjoin(root, i) for i in \
('usr/lib', 'usr/lib64', 'usr/lib32')])
if os.environ.has_key('LD_LIBRARY_PATH'):
denv['LD_LIBRARY_PATH'] += ':' + os.environ['LD_LIBRARY_PATH']
#INCLUDE_PATH
denv['INCLUDE_PATH'] = ':'.join([pjoin(root, i) for i in ('usr/include',)])
if os.environ.has_key('INCLUDE_PATH'):
denv['INCLUDE_PATH'] += ':' + os.environ['INCLUDE_PATH']
# Adds
for k,v in envAdds.items():
denv[k] = v
return denv
def availablePackages(pattern):
"""Returns a list of packages matching the given pattern.
The packages are returned as (category, package, version, revision) tuple.
No test for keywords or mask is performed. The function just returns
every matching pattern in the portage tree and installed overlays.
"""
return [portage.catpkgsplit(l) \
for l in cmd.getoutput('equery -q list -po ' + pattern).split()]
def normalize_cpv(cpv):
if type(cpv) == type(''):
try:
cpv_ = portage.catpkgsplit(cpv)
cpv_[-1]
cpv = cpv_
except:
cpv = availablePackages(cpv)[-1]
if cpv[-1] != 'r0':
return '%s/%s-%s-%s' % cpv
else:
return '%s/%s-%s' % cpv[:-1]
def getDependencies(package, env={}, split=False):
pkg = normalize_cpv(package)
cmd = ['emerge', '--ignore-default-opts', '='+pkg, '-poq']
proc = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE, env=env)
output = proc.communicate()[0]
if proc.returncode != 0:
return []
lines = output.strip().split('\n')
if not lines[0]:
return []
if split:
return [portage.catpkgsplit(shlex.split(l.strip())[-1]) for l in lines]
else:
return [shlex.split(l.strip())[-1] for l in lines]
def installDependencies(test):
# Adjust environment
denv = _getEnv(test['root'], dict(PKGDIR=test['pkgdir']))
# Retrieve dependencies
deps = getDependencies(test['package'], denv, False)
for i,d in enumerate(deps):
logfile = pjoin(test['logdir'], 'emergedep_%i.log' % i)
installPackage(test, package=d, env=test['dependenv'], logfile=logfile)
#def installPackage(package, env={}, root='/', pkgdir='usr/portage/packages',
# logfile=None):
def installPackage(test, package=None, env=None, logfile=None):
# TODO: rewrite docstring
"""Emerge a package in the given root.
package is the package to be emerged. It has to be a tuple
(category, package, version, revision).
env is a dictionary of KEY:VALUE pairs describing the environment changes
the package will be emerged with. It is useful to specifiy the compilers and
compiler flags. It is safe to use ACCEPT_KEYWORDS=* for testing purposes.
root is the directory where the packaged will be emerged. A non-root user
can use this function, provided he has write access to that directory.
pkgdir is the directory where the binary package will be placed. The user
has to be able to write in this directory.
The function has no return value and raises an exception in case of building
or emerging failure. Note: dependencies will NOT be emerged!
"""
if package is None:
package = test['package']
if env is None:
env = test['emergeenv']
if logfile is None:
logfile = pjoin(test['logdir'], 'emerge.log')
envAdds = env.copy()
envAdds['PKGDIR'] = test['pkgdir']
denv = _getEnv(test['root'], envAdds)
del envAdds
# Retrieve package string
pkg = normalize_cpv(package)
# Execute emerge command and log the results
benchutils.mkdir(dirname(logfile))
fout = file(logfile, 'w')
cmd = ['emerge', '--ignore-default-opts', '-OB', '=' + pkg]
p = sp.Popen(cmd, env=denv, stdout=fout, stderr=sp.STDOUT)
p.wait()
if p.returncode != 0:
# In case of error, print the whole emerge command
raise InstallException(p, ' '.join(cmd), logfile)
fout.write('\n\n' + 80*'#' + '\n\n')
# Unpack package onto root
archive = pjoin(test['pkgdir'], pkg+'.tbz2')
benchutils.mkdir(test['root'])
tarcmd = ['tar', 'xjvf', archive, '-C', test['root']]
fout.write(' '.join(tarcmd) + '\n' + 80*'-' + '\n')
p = sp.Popen(tarcmd, stdout=fout, stderr=sp.STDOUT)
p.wait()
if p.returncode != 0:
# In case of error, print the whole emerge command
raise InstallException(pkg, ' '.join(tarcmd), logfile)
# Close, return
fout.close()
if __name__ == '__main__':
# Just a test
from pprint import pprint
pprint(get_dependencies('sci-libs/blas-reference-3.3.1-r1'))
|