import operator import os import subprocess import sys from xml.dom import minidom scripts_dir = os.path.dirname(__file__) base_dir = os.path.dirname(scripts_dir) _cached_dname, _cached_dversion = None, None def _pipe_lower(args) : out, err = subprocess.Popen(args, stdout=subprocess.PIPE).communicate() return out.strip().lower() def get_distribution(): global _cached_dname, _cached_dversion if _cached_dname : return _cached_dname, _cached_dversion if 'SJH_DISTRIBUTION' in os.environ: _cached_dname, _cached_dversion = os.environ['SJH_DISTRIBUTION'].split('-') return _cached_dname, _cached_dversion try: _cached_dname = _pipe_lower(['lsb_release', '-is']) _cached_dversion = _pipe_lower(['lsb_release', '-rs']) except OSError: pass return _cached_dname, _cached_dversion def check_package(package): name, version = get_distribution() if name in ['fedora', 'mandrivalinux']: ret = subprocess.call(['rpm', '--quiet', '-q', package]) return ret == 0 elif name in ['ubuntu', 'debian']: cmd = ["dpkg-query", "-f='${status}'", "-W", package] out, err = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate() return out.find('install ok installed') != -1 return None def _check_suffix(name, suffixes) : """ Returns a list of all matching suffixes for . """ return [name for suffix in suffixes if name.endswith(suffix)] _unstable_names = { 'debian': 'unstable', 'fedora': 'rawhide', 'mandrivalinux': 'cooker', 'ubuntu': 'unstable', } def _parse_dependencies(dname, dversion): if not (dname and dversion): return [] suffixes = ['alldistros.xml', '%s-allversions.xml' % (dname,), '%s-%s.xml' % (dname, dversion)] dirname = os.path.join(base_dir, 'config', 'sysdeps') filenames = [os.path.join(dirname, fname) for fname in os.listdir(dirname) if _check_suffix(fname, suffixes)] # check whether we have a file matching the exact distro version if not [name for name in filenames if name.endswith(suffixes[-1])] : # will break for unknown distros, but that's fine # (=> bug report => add support for distro) uversion = _unstable_names[dname] if (dversion == uversion) : # no config for unstable return [] sys.stderr.write("Warning: unknown distro version, automatic fallback to %s.\n" % (uversion,)) return _parse_dependencies(dname, uversion) return [minidom.parse(fname) for fname in filenames if os.path.exists(fname)] _cached_packages = None def get_packages(): global _cached_packages if _cached_packages is not None : return _cached_packages dname, dversion = get_distribution() documents = _parse_dependencies(dname, dversion) _cached_packages = [] if not documents : return _cached_packages roots = [doc.childNodes[0] for doc in documents] for node in reduce(operator.add, [root.childNodes for root in roots]) : if node.nodeType == node.ELEMENT_NODE: if node.nodeName == 'package': name = node.getAttribute('name') if node.hasAttribute('source'): source = node.getAttribute('source') else: source = None _cached_packages.append((name, source)) return _cached_packages