base_utils.py revision e7a170fb097da48af81ca598e29643f3e7cca584
1c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh"""Convenience functions for use by tests or whomever.
2c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh"""
3c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
4ff88e4eac1757a065f2c69f48ac3c63831fe4f04mblighimport os,os.path,shutil,urllib,sys,signal,commands,pickle
5bc2867dae46688cf0f6481a2190da7f32e08a3c7apwfrom error import *
64e75b0d3b020f901456217fb8ff0d7d4391fa869mblighimport re,string
7f4c35322b200d65f41a8332b4f3503beb497840dmbligh
8f4c35322b200d65f41a8332b4f3503beb497840dmblighdef grep(pattern, file):
97bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	"""
107bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	This is mainly to fix the return code inversion from grep
117bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	Also handles compressed files.
127bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh
137bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	returns 1 if the pattern is present in the file, 0 if not.
147bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	"""
157bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	command = 'grep "%s" > /dev/null' % pattern
167bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	ret = cat_file_to_cmd(file, command, ignorestatus = 1)
177bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	return not ret
18f4c35322b200d65f41a8332b4f3503beb497840dmbligh
19f4c35322b200d65f41a8332b4f3503beb497840dmbligh
20c86b0b45cd0198d99d271a79f8b6de29feb98cd5mblighdef difflist(list1, list2):
21c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""returns items in list2 that are not in list1"""
22f4c35322b200d65f41a8332b4f3503beb497840dmbligh	diff = [];
23f4c35322b200d65f41a8332b4f3503beb497840dmbligh	for x in list2:
24f4c35322b200d65f41a8332b4f3503beb497840dmbligh		if x not in list1:
25f4c35322b200d65f41a8332b4f3503beb497840dmbligh			diff.append(x)
26f4c35322b200d65f41a8332b4f3503beb497840dmbligh	return diff
27f4c35322b200d65f41a8332b4f3503beb497840dmbligh
28c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
297bdbfbdf088f9c2a72c199d5a530194bb2ac257fmblighdef cat_file_to_cmd(file, command, ignorestatus = 0):
307bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	"""
317bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	equivalent to 'cat file | command' but knows to use
327bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	zcat or bzcat if appropriate
337bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh	"""
34712cd145672c0033a55173717787c54cd68e6b83mbligh	if not os.path.isfile(file):
35712cd145672c0033a55173717787c54cd68e6b83mbligh		raise NameError, 'invalid file %s to cat to command %s' % file, command
36f4c35322b200d65f41a8332b4f3503beb497840dmbligh	if file.endswith('.bz2'):
377bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh		return system('bzcat ' + file + ' | ' + command, ignorestatus)
383d914919f7c22adae7c54e4a6d2378b1fc6efaf3mbligh	elif (file.endswith('.gz') or file.endswith('.tgz')):
397bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh		return system('zcat ' + file + ' | ' + command, ignorestatus)
40f4c35322b200d65f41a8332b4f3503beb497840dmbligh	else:
417bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh		return system('cat ' + file + ' | ' + command, ignorestatus)
42712cd145672c0033a55173717787c54cd68e6b83mbligh
43c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
44712cd145672c0033a55173717787c54cd68e6b83mblighdef extract_tarball_to_dir(tarball, dir):
45c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
46c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	Extract a tarball to a specified directory name instead of whatever
47c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	the top level of a tarball is - useful for versioned directory names, etc
48c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
49712cd145672c0033a55173717787c54cd68e6b83mbligh	if os.path.exists(dir):
50712cd145672c0033a55173717787c54cd68e6b83mbligh		raise NameError, 'target %s already exists' % dir
51712cd145672c0033a55173717787c54cd68e6b83mbligh	pwd = os.getcwd()
52712cd145672c0033a55173717787c54cd68e6b83mbligh	os.chdir(os.path.dirname(os.path.abspath(dir)))
53712cd145672c0033a55173717787c54cd68e6b83mbligh	newdir = extract_tarball(tarball)
54712cd145672c0033a55173717787c54cd68e6b83mbligh	os.rename(newdir, dir)
55712cd145672c0033a55173717787c54cd68e6b83mbligh	os.chdir(pwd)
56712cd145672c0033a55173717787c54cd68e6b83mbligh
57f4c35322b200d65f41a8332b4f3503beb497840dmbligh
58712cd145672c0033a55173717787c54cd68e6b83mblighdef extract_tarball(tarball):
59c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Returns the first found newly created directory by the tarball extraction"""
60712cd145672c0033a55173717787c54cd68e6b83mbligh	oldlist = os.listdir('.')
61712cd145672c0033a55173717787c54cd68e6b83mbligh	cat_file_to_cmd(tarball, 'tar xf -')
62712cd145672c0033a55173717787c54cd68e6b83mbligh	newlist = os.listdir('.')
63712cd145672c0033a55173717787c54cd68e6b83mbligh	newfiles = difflist(oldlist, newlist)   # what is new dir ?
64712cd145672c0033a55173717787c54cd68e6b83mbligh	new_dir = None
65712cd145672c0033a55173717787c54cd68e6b83mbligh	for newfile in newfiles:
66712cd145672c0033a55173717787c54cd68e6b83mbligh		if (os.path.isdir(newfile)):
67712cd145672c0033a55173717787c54cd68e6b83mbligh			return newfile
68712cd145672c0033a55173717787c54cd68e6b83mbligh	raise NameError, "extracting tarball produced no dir"
69712cd145672c0033a55173717787c54cd68e6b83mbligh
70cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
7178e17027dd041ed8ff7fb2736201a6146a3b93a9mblighdef update_version(srcdir, new_version, install, *args, **dargs):
72c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Make sure srcdir is version new_version
73c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
74c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	If not, delete it and install() the new version
75c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
767290556f1f826a79acf6f76ca3f5a04264fc521dmbligh	versionfile = srcdir + '/.version'
77ff88e4eac1757a065f2c69f48ac3c63831fe4f04mbligh	if os.path.exists(srcdir):
78ff88e4eac1757a065f2c69f48ac3c63831fe4f04mbligh		if os.path.exists(versionfile):
79ff88e4eac1757a065f2c69f48ac3c63831fe4f04mbligh			old_version = pickle.load(open(versionfile, 'r'))
80ff88e4eac1757a065f2c69f48ac3c63831fe4f04mbligh			if (old_version != new_version):
81ff88e4eac1757a065f2c69f48ac3c63831fe4f04mbligh				system('rm -rf ' + srcdir)
82ff88e4eac1757a065f2c69f48ac3c63831fe4f04mbligh		else:
837290556f1f826a79acf6f76ca3f5a04264fc521dmbligh			system('rm -rf ' + srcdir)
847290556f1f826a79acf6f76ca3f5a04264fc521dmbligh	if not os.path.exists(srcdir):
8578e17027dd041ed8ff7fb2736201a6146a3b93a9mbligh		install(*args, **dargs)
867290556f1f826a79acf6f76ca3f5a04264fc521dmbligh		if os.path.exists(srcdir):
877290556f1f826a79acf6f76ca3f5a04264fc521dmbligh			pickle.dump(new_version, open(versionfile, 'w'))
887290556f1f826a79acf6f76ca3f5a04264fc521dmbligh
897290556f1f826a79acf6f76ca3f5a04264fc521dmbligh
90ea30c8a19ee292ee57b5223ca079f7a311195b41mblighdef is_url(path):
91c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""true if path is a url
92c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
93c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	# should cope with other url types here, but we only handle http and ftp
94ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh	if (path.startswith('http://')) or (path.startswith('ftp://')):
95ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh		return 1
96ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh	return 0
97ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh
98cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
99f4c35322b200d65f41a8332b4f3503beb497840dmblighdef get_file(src, dest):
100c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""get a file, either from url or local"""
1013118661bc4d4d57438013bb47ac63e78c7bca03dmbligh	if (src == dest):      # no-op here allows clean overrides in tests
1023118661bc4d4d57438013bb47ac63e78c7bca03dmbligh		return
103ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh	if (is_url(src)):
104f4c35322b200d65f41a8332b4f3503beb497840dmbligh		print 'PWD: ' + os.getcwd()
105f4c35322b200d65f41a8332b4f3503beb497840dmbligh		print 'Fetching \n\t', src, '\n\t->', dest
106f4c35322b200d65f41a8332b4f3503beb497840dmbligh		try:
107f4c35322b200d65f41a8332b4f3503beb497840dmbligh			urllib.urlretrieve(src, dest)
108f4c35322b200d65f41a8332b4f3503beb497840dmbligh		except IOError:
109f4c35322b200d65f41a8332b4f3503beb497840dmbligh			sys.stderr.write("Unable to retrieve %s (to %s)\n" % (src, dest))
110f4c35322b200d65f41a8332b4f3503beb497840dmbligh			sys.exit(1)
111f4c35322b200d65f41a8332b4f3503beb497840dmbligh		return dest
112f4c35322b200d65f41a8332b4f3503beb497840dmbligh	shutil.copyfile(src, dest)
113f4c35322b200d65f41a8332b4f3503beb497840dmbligh	return dest
114f4c35322b200d65f41a8332b4f3503beb497840dmbligh
115ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh
1168264186be2d5531ca903fe34a87bd5c79cce5f80mblighdef unmap_url(srcdir, src, destdir = '.'):
11752508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh	"""
11852508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh	Receives either a path to a local file or a URL.
11952508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh	returns either the path to the local file, or the fetched URL
12052508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh
12152508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh	unmap_url('/usr/src', 'foo.tar', '/tmp')
12252508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh				= '/usr/src/foo.tar'
12352508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh	unmap_url('/usr/src', 'http://site/file', '/tmp')
12452508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh				= '/tmp/file'
12552508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh				(after retrieving it)
12652508630c5a7511c452bfd94c7ab1c0e1d588d00mbligh	"""
127ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh	if is_url(src):
128ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh		dest = destdir + '/' + os.path.basename(src)
129ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh		get_file(src, dest)
130ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh		return dest
1318264186be2d5531ca903fe34a87bd5c79cce5f80mbligh	else:
1328264186be2d5531ca903fe34a87bd5c79cce5f80mbligh		return srcdir + '/' + src
133ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh
134ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh
135f4c35322b200d65f41a8332b4f3503beb497840dmblighdef basename(path):
136f4c35322b200d65f41a8332b4f3503beb497840dmbligh	i = path.rfind('/');
137f4c35322b200d65f41a8332b4f3503beb497840dmbligh	return path[i+1:]
138f4c35322b200d65f41a8332b4f3503beb497840dmbligh
139f4c35322b200d65f41a8332b4f3503beb497840dmbligh
140f4c35322b200d65f41a8332b4f3503beb497840dmblighdef force_copy(src, dest):
141c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Replace dest with a new copy of src, even if it exists"""
142f4c35322b200d65f41a8332b4f3503beb497840dmbligh	if os.path.isfile(dest):
143f4c35322b200d65f41a8332b4f3503beb497840dmbligh		os.remove(dest)
1441e8858e6f825fb9eba4a87b921911c6f398ca727mbligh	if os.path.isdir(dest):
1451e8858e6f825fb9eba4a87b921911c6f398ca727mbligh		dest = os.path.join(dest, os.path.basename(src))
146f4c35322b200d65f41a8332b4f3503beb497840dmbligh	return shutil.copyfile(src, dest)
147f4c35322b200d65f41a8332b4f3503beb497840dmbligh
148f4c35322b200d65f41a8332b4f3503beb497840dmbligh
149fdbcaec15092d8b4af80970c495038bdf9b0e63fmblighdef force_link(src, dest):
150fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh	"""Link src to dest, overwriting it if it exists"""
151fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh	return system("ln -sf %s %s" % (src, dest))
152fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
153fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
154cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmblighdef file_contains_pattern(file, pattern):
155c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Return true if file contains the specified egrep pattern"""
156cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	if not os.path.isfile(file):
157cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		raise NameError, 'file %s does not exist' % file
1585c1e26aa615e5a2587fce3a7d093bc05f2d1dc94mbligh	return not system('egrep -q "' + pattern + '" ' + file, ignorestatus = 1)
159cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
160cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
161cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmblighdef list_grep(list, pattern):
162c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""True if any item in list matches the specified pattern."""
163cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	compiled = re.compile(pattern)
164cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	for line in list:
165cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		match = compiled.search(line)
166cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		if (match):
167cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh			return 1
168cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	return 0
169cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
17042b81ca63a0ab336b844e9c5cce6fe30dae85357mblighdef get_os_vendor():
17142b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	"""Try to guess what's the os vendor
17242b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	"""
17342b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	issue = '/etc/issue'
17442b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh
17542b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	if not os.path.isfile(issue):
17642b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh		return 'Unknown'
17742b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh
17842b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	if file_contains_pattern(issue, 'Red Hat'):
17942b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh		return 'Red Hat'
18042b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	elif file_contains_pattern(issue, 'Fedora Core'):
18142b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh		return 'Fedora Core'
18242b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	elif file_contains_pattern(issue, 'SUSE'):
18342b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh		return 'SUSE'
18442b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	elif file_contains_pattern(issue, 'Ubuntu'):
18542b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh		return 'Ubuntu'
18642b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh	else:
18742b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh		return 'Unknown'
18842b81ca63a0ab336b844e9c5cce6fe30dae85357mbligh
189cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
190f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmblighdef get_vmlinux():
191c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Return the full path to vmlinux
192c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
193c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	Ahem. This is crap. Pray harder. Bad Martin.
194c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
195ad849eea0958e6fae31dbc6ca46c0fd10ef72fcambligh	vmlinux = '/boot/vmlinux-%s' % system_output('uname -r')
196662a2a2695f7f1b492e8dbd7f60db242f81e7cb2mbligh	if os.path.isfile(vmlinux):
197662a2a2695f7f1b492e8dbd7f60db242f81e7cb2mbligh		return vmlinux
19817dbf0564f5aaf66820a000f14e3006125b303f9mbligh	vmlinux = '/lib/modules/%s/build/vmlinux' % system_output('uname -r')
19917dbf0564f5aaf66820a000f14e3006125b303f9mbligh	if os.path.isfile(vmlinux):
20017dbf0564f5aaf66820a000f14e3006125b303f9mbligh		return vmlinux
201662a2a2695f7f1b492e8dbd7f60db242f81e7cb2mbligh	return None
202f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
203f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
204f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmblighdef get_systemmap():
205c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Return the full path to System.map
206c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
207c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	Ahem. This is crap. Pray harder. Bad Martin.
208c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
209ad849eea0958e6fae31dbc6ca46c0fd10ef72fcambligh	map = '/boot/System.map-%s' % system_output('uname -r')
210662a2a2695f7f1b492e8dbd7f60db242f81e7cb2mbligh	if os.path.isfile(map):
211662a2a2695f7f1b492e8dbd7f60db242f81e7cb2mbligh		return map
21217dbf0564f5aaf66820a000f14e3006125b303f9mbligh	map = '/lib/modules/%s/build/System.map' % system_output('uname -r')
21317dbf0564f5aaf66820a000f14e3006125b303f9mbligh	if os.path.isfile(map):
21417dbf0564f5aaf66820a000f14e3006125b303f9mbligh		return map
215662a2a2695f7f1b492e8dbd7f60db242f81e7cb2mbligh	return None
21667b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh
21767b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh
21867b5ece7667fc71429ee05b07ac7654ed5a05df7mblighdef get_modules_dir():
219c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Return the modules dir for the running kernel version"""
22067b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh	kernel_version = system_output('uname -r')
22167b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh	return '/lib/modules/%s/kernel' % kernel_version
222f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
223f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
2245970cf057674accdb00a7742eae50e40c57e52d0mblighdef get_cpu_arch():
225c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Work out which CPU architecture we're running on"""
226cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	f = open('/proc/cpuinfo', 'r')
227cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	cpuinfo = f.readlines()
228cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	f.close()
229cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	if list_grep(cpuinfo, '^cpu.*(RS64|POWER3|Broadband Engine)'):
230cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		return 'power'
231cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	elif list_grep(cpuinfo, '^cpu.*POWER4'):
232cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		return 'power4'
233cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	elif list_grep(cpuinfo, '^cpu.*POWER5'):
234cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		return 'power5'
235cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	elif list_grep(cpuinfo, '^cpu.*POWER6'):
236cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		return 'power6'
237cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	elif list_grep(cpuinfo, '^cpu.*PPC970'):
238cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		return 'power970'
239cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	elif list_grep(cpuinfo, 'Opteron'):
240cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh		return 'x86_64'
241cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh	elif list_grep(cpuinfo, 'GenuineIntel') and list_grep(cpuinfo, '48 bits virtual'):
242f4c35322b200d65f41a8332b4f3503beb497840dmbligh		return 'x86_64'
243f4c35322b200d65f41a8332b4f3503beb497840dmbligh	else:
244f4c35322b200d65f41a8332b4f3503beb497840dmbligh		return 'i386'
245f4c35322b200d65f41a8332b4f3503beb497840dmbligh
246f4c35322b200d65f41a8332b4f3503beb497840dmbligh
247548f29af9e38f87c3609838f5aabeac94bb69f13mblighdef get_current_kernel_arch():
248548f29af9e38f87c3609838f5aabeac94bb69f13mbligh	"""Get the machine architecture, now just a wrap of 'uname -m'."""
249548f29af9e38f87c3609838f5aabeac94bb69f13mbligh	return os.popen('uname -m').read().rstrip()
250cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
251cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
252fdbcaec15092d8b4af80970c495038bdf9b0e63fmblighdef get_file_arch(filename):
253fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh	# -L means follow symlinks
254fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh	file_data = system_output('file -L ' + filename)
255fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh	if file_data.count('80386'):
256fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh		return 'i386'
257fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh	return None
258fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
259fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
260548f29af9e38f87c3609838f5aabeac94bb69f13mblighdef kernelexpand(kernel, args=None):
261f4c35322b200d65f41a8332b4f3503beb497840dmbligh	# if not (kernel.startswith('http://') or kernel.startswith('ftp://') or os.path.isfile(kernel)):
2625629af0f98d4f1f90c58e7ed81b130702271915ambligh	if kernel.find('/') < 0:     # contains no path.
263534015f5590bce2348413c02ec119936ee9e1a80mbligh		autodir = os.environ['AUTODIR']
264534015f5590bce2348413c02ec119936ee9e1a80mbligh		kernelexpand = os.path.join(autodir, 'tools/kernelexpand')
265548f29af9e38f87c3609838f5aabeac94bb69f13mbligh		if args:
266548f29af9e38f87c3609838f5aabeac94bb69f13mbligh			kernelexpand += ' ' + args
2675629af0f98d4f1f90c58e7ed81b130702271915ambligh		w, r = os.popen2(kernelexpand + ' ' + kernel)
268f4c35322b200d65f41a8332b4f3503beb497840dmbligh
269f4c35322b200d65f41a8332b4f3503beb497840dmbligh		kernel = r.readline().strip()
270f4c35322b200d65f41a8332b4f3503beb497840dmbligh		r.close()
271f4c35322b200d65f41a8332b4f3503beb497840dmbligh		w.close()
272534015f5590bce2348413c02ec119936ee9e1a80mbligh	return kernel.split()
273f4c35322b200d65f41a8332b4f3503beb497840dmbligh
274f4c35322b200d65f41a8332b4f3503beb497840dmbligh
275f4c35322b200d65f41a8332b4f3503beb497840dmblighdef count_cpus():
276c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""number of CPUs in the local machine according to /proc/cpuinfo"""
277f4c35322b200d65f41a8332b4f3503beb497840dmbligh	f = file('/proc/cpuinfo', 'r')
278f4c35322b200d65f41a8332b4f3503beb497840dmbligh	cpus = 0
279f4c35322b200d65f41a8332b4f3503beb497840dmbligh	for line in f.readlines():
280f4c35322b200d65f41a8332b4f3503beb497840dmbligh		if line.startswith('processor'):
281f4c35322b200d65f41a8332b4f3503beb497840dmbligh			cpus += 1
282f4c35322b200d65f41a8332b4f3503beb497840dmbligh	return cpus
283f4c35322b200d65f41a8332b4f3503beb497840dmbligh
284e7a170fb097da48af81ca598e29643f3e7cca584mbligh
285e7a170fb097da48af81ca598e29643f3e7cca584mbligh# Returns total memory in kb
286e7a170fb097da48af81ca598e29643f3e7cca584mblighdef memtotal():
287e7a170fb097da48af81ca598e29643f3e7cca584mbligh	memtotal = system_output('grep MemTotal /proc/meminfo')
288e7a170fb097da48af81ca598e29643f3e7cca584mbligh	return int(re.search(r'\d+', memtotal).group(0))
289e7a170fb097da48af81ca598e29643f3e7cca584mbligh
290e7a170fb097da48af81ca598e29643f3e7cca584mbligh
291a975fb6b4cb50f5d48b06d84aba97ca67c0adea4mblighdef system(cmd, ignorestatus = 0):
292c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""os.system replacement
293c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
294c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	We have our own definition of system here, as the stock os.system doesn't
295c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	correctly handle sigpipe
296c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	(ie things like "yes | head" will hang because yes doesn't get the SIGPIPE).
297c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
298c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	Also the stock os.system didn't raise errors based on exit status, this
299c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	version does unless you explicitly specify ignorestatus=1
300c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
301f4c35322b200d65f41a8332b4f3503beb497840dmbligh	signal.signal(signal.SIGPIPE, signal.SIG_DFL)
302f4c35322b200d65f41a8332b4f3503beb497840dmbligh	try:
303bc2867dae46688cf0f6481a2190da7f32e08a3c7apw		status = os.system(cmd)
304f4c35322b200d65f41a8332b4f3503beb497840dmbligh	finally:
305f4c35322b200d65f41a8332b4f3503beb497840dmbligh		signal.signal(signal.SIGPIPE, signal.SIG_IGN)
306f4c35322b200d65f41a8332b4f3503beb497840dmbligh
30767b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh	if ((status != 0) and not ignorestatus):
308a975fb6b4cb50f5d48b06d84aba97ca67c0adea4mbligh		raise CmdError(cmd, status)
309a975fb6b4cb50f5d48b06d84aba97ca67c0adea4mbligh	return status
3103d914919f7c22adae7c54e4a6d2378b1fc6efaf3mbligh
3113d914919f7c22adae7c54e4a6d2378b1fc6efaf3mbligh
31267b5ece7667fc71429ee05b07ac7654ed5a05df7mblighdef system_output(command, ignorestatus = 0):
313c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Run command and return its output
314c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
315c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	ignorestatus
316c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh		whether to raise a CmdError if command has a nonzero exit status
317c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
31867b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh	(result, data) = commands.getstatusoutput(command)
31967b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh	if ((result != 0) and not ignorestatus):
32067b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh		raise CmdError, 'command failed: ' + command
32167b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh	return data
32267b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh
32367b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh
324f4c35322b200d65f41a8332b4f3503beb497840dmblighdef where_art_thy_filehandles():
325c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Dump the current list of filehandles"""
326f4c35322b200d65f41a8332b4f3503beb497840dmbligh	os.system("ls -l /proc/%d/fd >> /dev/tty" % os.getpid())
327f4c35322b200d65f41a8332b4f3503beb497840dmbligh
328f4c35322b200d65f41a8332b4f3503beb497840dmbligh
329f4c35322b200d65f41a8332b4f3503beb497840dmblighdef print_to_tty(string):
330c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Output string straight to the tty"""
331f4c35322b200d65f41a8332b4f3503beb497840dmbligh	os.system("echo " + string + " >> /dev/tty")
332f4c35322b200d65f41a8332b4f3503beb497840dmbligh
333f4c35322b200d65f41a8332b4f3503beb497840dmbligh
334b8a14e358b611f2d97c06e863be9b53ab2bedeefmblighdef dump_object(object):
335c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""Dump an object's attributes and methods
336c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
337c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	kind of like dir()
338c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""
339b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh	for item in object.__dict__.iteritems():
340b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh		print item
341b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh		try:
342b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh			(key,value) = item
343b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh			dump_object(value)
344b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh		except:
345b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh			continue
346b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh
347b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh
3484b089663460063b638124ff665f38d2fe7427648mblighdef environ(env_key):
349c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""return the requested environment variable, or '' if unset"""
3504b089663460063b638124ff665f38d2fe7427648mbligh	if (os.environ.has_key(env_key)):
351d931a5894a9cd50909ec5aabf7133ea944992b5dmbligh		return os.environ[env_key]
3524b089663460063b638124ff665f38d2fe7427648mbligh	else:
3534b089663460063b638124ff665f38d2fe7427648mbligh		return ''
3544b089663460063b638124ff665f38d2fe7427648mbligh
3554b089663460063b638124ff665f38d2fe7427648mbligh
3564b089663460063b638124ff665f38d2fe7427648mblighdef prepend_path(newpath, oldpath):
357c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""prepend newpath to oldpath"""
3584b089663460063b638124ff665f38d2fe7427648mbligh	if (oldpath):
3594b089663460063b638124ff665f38d2fe7427648mbligh		return newpath + ':' + oldpath
3604b089663460063b638124ff665f38d2fe7427648mbligh	else:
3614b089663460063b638124ff665f38d2fe7427648mbligh		return newpath
3624b089663460063b638124ff665f38d2fe7427648mbligh
3634b089663460063b638124ff665f38d2fe7427648mbligh
3644b089663460063b638124ff665f38d2fe7427648mblighdef append_path(oldpath, newpath):
365c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh	"""append newpath to oldpath"""
3664b089663460063b638124ff665f38d2fe7427648mbligh	if (oldpath):
3674b089663460063b638124ff665f38d2fe7427648mbligh		return oldpath + ':' + newpath
3684b089663460063b638124ff665f38d2fe7427648mbligh	else:
3694b089663460063b638124ff665f38d2fe7427648mbligh		return newpath
3704b089663460063b638124ff665f38d2fe7427648mbligh
3714b089663460063b638124ff665f38d2fe7427648mbligh
3724e75b0d3b020f901456217fb8ff0d7d4391fa869mblighdef avgtime_print(dir):
3734e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	""" Calculate some benchmarking statistics.
3744e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	    Input is a directory containing a file called 'time'.
3754e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	    File contains one-per-line results of /usr/bin/time.
3764e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	    Output is average Elapsed, User, and System time in seconds,
3774e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	      and average CPU percentage.
3784e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	"""
3794e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	f = open(dir + "/time")
3804e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	user = system = elapsed = cpu = count = 0
3814e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	r = re.compile('([\d\.]*)user ([\d\.]*)system (\d*):([\d\.]*)elapsed (\d*)%CPU')
3824e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	for line in f.readlines():
3834e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh		try:
3844e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh			s = r.match(line);
385e1ee267d3c02ceba3b6168ad34d4b27d0bbc626ambligh			user += float(s.group(1))
386e1ee267d3c02ceba3b6168ad34d4b27d0bbc626ambligh			system += float(s.group(2))
387e1ee267d3c02ceba3b6168ad34d4b27d0bbc626ambligh			elapsed += (float(s.group(3)) * 60) + float(s.group(4))
388e1ee267d3c02ceba3b6168ad34d4b27d0bbc626ambligh			cpu += float(s.group(5))
3894e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh			count += 1
3904e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh		except:
3914e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh			raise ValueError("badly formatted times")
3924e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
3934e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	f.close()
3944e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	return "Elapsed: %0.2fs User: %0.2fs System: %0.2fs CPU: %0.0f%%" % \
3954e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh	      (elapsed/count, user/count, system/count, cpu/count)
3964e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
3974e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
398f06db0f9b381737b9c85bef1c23ea1a1ca73c559mblighdef running_config():
399f06db0f9b381737b9c85bef1c23ea1a1ca73c559mbligh	"""
400f06db0f9b381737b9c85bef1c23ea1a1ca73c559mbligh	Return path of config file of the currently running kernel
401f06db0f9b381737b9c85bef1c23ea1a1ca73c559mbligh	"""
402f06db0f9b381737b9c85bef1c23ea1a1ca73c559mbligh	for config in ('/proc/config.gz', \
403f06db0f9b381737b9c85bef1c23ea1a1ca73c559mbligh		       '/boot/config-%s' % system_output('uname -r') ):
404f06db0f9b381737b9c85bef1c23ea1a1ca73c559mbligh		if os.path.isfile(config):
405f06db0f9b381737b9c85bef1c23ea1a1ca73c559mbligh			return config
406f06db0f9b381737b9c85bef1c23ea1a1ca73c559mbligh	return None
4079ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh
4089ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh
4099ec8acc50c0fe06a40353db0df8e135cebb2ec58mblighdef cpu_online_map():
4109ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh	"""
4119ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh	Check out the available cpu online map
4129ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh	"""
4139ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh	cpus = []
4149ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh	for line in open('/proc/cpuinfo', 'r').readlines():
4159ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh		if line.startswith('processor'):
4169ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh			cpus.append(line.split()[2]) # grab cpu number
4179ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh	return cpus
418663e4f664465dbaa9e86c5c20d035ad9bd1e65edmbligh
419663e4f664465dbaa9e86c5c20d035ad9bd1e65edmbligh
420663e4f664465dbaa9e86c5c20d035ad9bd1e65edmblighdef check_glibc_ver(ver):
421663e4f664465dbaa9e86c5c20d035ad9bd1e65edmbligh	glibc_ver = commands.getoutput('ldd --version').splitlines()[0]
422cabfdafe37abd042e3b347735d3535b282ee4a51mbligh	glibc_ver = re.search(r'(\d+\.\d+(\.\d+)?)', glibc_ver).group()
423ea97ab8d339c659a3269037f19788954a98e704cmbligh	if glibc_ver.split('.') < ver.split('.'):
424ea97ab8d339c659a3269037f19788954a98e704cmbligh		raise "Glibc is too old (%s). Glibc >= %s is needed." % \
425ea97ab8d339c659a3269037f19788954a98e704cmbligh							(glibc_ver, ver)
426ea97ab8d339c659a3269037f19788954a98e704cmbligh
427ea97ab8d339c659a3269037f19788954a98e704cmbligh
428ea97ab8d339c659a3269037f19788954a98e704cmblighdef check_python_version():
429ea97ab8d339c659a3269037f19788954a98e704cmbligh	py_version = (sys.version).split(' ')[0]
430ea97ab8d339c659a3269037f19788954a98e704cmbligh	version = py_version.split('.')[0:2]
431ea97ab8d339c659a3269037f19788954a98e704cmbligh	if [int(x) for x in version] < [2, 4]:
4321f22fe6567a7f5e9f6352a787057e8e1cd2dd521apw                for new in ('/usr/bin/python2.4', '/usr/local/bin/python2.4'):
4331f22fe6567a7f5e9f6352a787057e8e1cd2dd521apw                        if os.path.exists(new):
4341f22fe6567a7f5e9f6352a787057e8e1cd2dd521apw                                sys.argv.insert(0, new)
4351f22fe6567a7f5e9f6352a787057e8e1cd2dd521apw                                os.execv(sys.argv[0], sys.argv)
436ea97ab8d339c659a3269037f19788954a98e704cmbligh		raise "Python 2.4 or newer is needed"
437