/usr/lib/python2.7/dist-packages/dogtail/distro.py is in python-dogtail 0.9.0-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 | """Handles differences between different distributions
Authors: Dave Malcolm <dmalcolm@redhat.com>, Zack Cerza <zcerza@redhat.com>"""
__author__ = "Dave Malcolm <dmalcolm@redhat.com>, Zack Cerza <zcerza@redhat.com>"
import os
import re
from version import Version
from logging import debugLogger as logger
class DistributionNotSupportedError(Exception): # pragma: no cover
"""
This distribution is not supported.
"""
PATCH_MESSAGE = "Please send patches to dogtail-devel-list@gnome.org"
def __init__(self, distro):
self.distro = distro
def __str__(self):
return self.distro + ". " + DistributionNotSupportedError.PATCH_MESSAGE
class PackageNotFoundError(Exception):
"""
Error finding the requested package.
"""
pass
global packageDb
global distro
class PackageDb(object):
"""
Class to abstract the details of whatever software package database is in
use (RPM, APT, etc)
"""
def __init__(self):
self.prefix = '/usr'
self.localePrefixes = [self.prefix + '/share/locale']
def getVersion(self, packageName):
"""
Method to get the version of an installed package as a Version
instance (or raise an exception if not found)
Note: does not know about distributions' internal revision numbers.
"""
raise NotImplementedError
def getFiles(self, packageName):
"""
Method to get a list of filenames owned by the package, or raise an
exception if not found.
"""
raise NotImplementedError
def getMoFiles(self, locale=None):
"""
Method to get a list of all .mo files on the system, optionally for a
specific locale.
"""
moFiles = {}
def appendIfMoFile(moFiles, dirName, fNames):
import re
for fName in fNames:
if re.match('(.*)\\.mo', fName):
moFiles[dirName + '/' + fName] = None
for localePrefix in self.localePrefixes:
if locale:
localePrefix = localePrefix + '/' + locale
os.path.walk(localePrefix, appendIfMoFile, moFiles)
return moFiles.keys()
def getDependencies(self, packageName):
"""
Method to get a list of unique package names that this package
is dependent on, or raise an exception if the package is not
found.
"""
raise NotImplementedError
class _RpmPackageDb(PackageDb): # pragma: no cover
def __init__(self):
PackageDb.__init__(self)
def getVersion(self, packageName):
import rpm
ts = rpm.TransactionSet()
for header in ts.dbMatch("name", packageName):
return Version.fromString(header["version"])
raise PackageNotFoundError(packageName)
def getFiles(self, packageName):
import rpm
ts = rpm.TransactionSet()
for header in ts.dbMatch("name", packageName):
return header["filenames"]
raise PackageNotFoundError(packageName)
def getDependencies(self, packageName):
import rpm
ts = rpm.TransactionSet()
for header in ts.dbMatch("name", packageName):
# Simulate a set using a hash (to a dummy value);
# sets were only added in Python 2.4
result = {}
# Get the list of requirements; these are
# sometimes package names, but can also be
# so-names of libraries, and invented virtual
# ids
for requirement in header[rpm.RPMTAG_REQUIRES]:
# Get the name of the package providing
# this requirement:
for depPackageHeader in ts.dbMatch("provides", requirement):
depName = depPackageHeader['name']
if depName != packageName:
# Add to the Hash with a dummy value
result[depName] = None
return result.keys()
raise PackageNotFoundError(packageName)
class _AptPackageDb(PackageDb):
def __init__(self):
PackageDb.__init__(self)
self.cache = None
def getVersion(self, packageName):
if not self.cache:
import apt_pkg
apt_pkg.init()
self.cache = apt_pkg.Cache()
packages = self.cache.packages
for package in packages:
if package.name == packageName:
verString = re.match(
'.*Ver:\'(.*)-.*\' Section:', str(package.current_ver)).group(1)
return Version.fromString(verString)
raise PackageNotFoundError(packageName)
def getFiles(self, packageName):
files = []
list = os.popen('dpkg -L %s' % packageName).readlines()
if not list:
raise PackageNotFoundError(packageName)
else:
for line in list:
file = line.strip()
if file:
files.append(file)
return files
def getDependencies(self, packageName):
# Simulate a set using a hash (to a dummy value);
# sets were only added in Python 2.4
result = {}
if not self.cache:
import apt_pkg
apt_pkg.init()
self.cache = apt_pkg.Cache()
packages = self.cache.packages
for package in packages:
if package.name == packageName:
current = package.current_ver
if not current:
raise PackageNotFoundError(packageName)
depends = current.depends_list
list = depends['Depends']
for dependency in list:
name = dependency[0].target_pkg.name
# Add to the hash using a dummy value
result[name] = None
return result.keys()
class _UbuntuAptPackageDb(_AptPackageDb):
def __init__(self):
_AptPackageDb.__init__(self)
self.localePrefixes.append(self.prefix + '/share/locale-langpack')
class _PortagePackageDb(PackageDb): # pragma: no cover
def __init__(self):
PackageDb.__init__(self)
def getVersion(self, packageName):
# the portage utilities are almost always going to be in
# /usr/lib/portage/pym
import sys
sys.path.append('/usr/lib/portage/pym')
import portage
# FIXME: this takes the first package returned in the list, in the
# case that there are slotted packages, and removes the leading
# category such as 'sys-apps'
gentooPackageName = portage.db["/"][
"vartree"].dbapi.match(packageName)[0].split('/')[1]
# this removes the distribution specific versioning returning only the
# upstream version
upstreamVersion = portage.pkgsplit(gentooPackageName)[1]
# print "Version of package is: " + upstreamVersion
return Version.fromString(upstreamVersion)
class _ConaryPackageDb(PackageDb): # pragma: no cover
def __init__(self):
PackageDb.__init__(self)
def getVersion(self, packageName):
from conaryclient import ConaryClient
client = ConaryClient()
dbVersions = client.db.getTroveVersionList(packageName)
if not len(dbVersions):
raise PackageNotFoundError(packageName)
return dbVersions[0].trailingRevision().asString().split("-")[0]
# getVersion not implemented because on Solaris multiple modules are installed
# in single packages, so it is hard to tell what version number of a specific
# module.
class _SolarisPackageDb(PackageDb): # pragma: no cover
def __init__(self):
PackageDb.__init__(self)
class JhBuildPackageDb(PackageDb): # pragma: no cover
def __init__(self):
PackageDb.__init__(self)
prefixes = []
prefixes.append(os.environ['LD_LIBRARY_PATH'])
prefixes.append(os.environ['XDG_CONFIG_DIRS'])
prefixes.append(os.environ['PKG_CONFIG_PATH'])
self.prefix = os.path.commonprefix(prefixes)
self.localePrefixes.append(self.prefix + '/share/locale')
def getDependencies(self, packageName):
result = {}
lines = os.popen('jhbuild list ' + packageName).readlines()
for line in lines:
if line:
result[line.strip()] = None
return result.keys()
class Distro(object):
"""
Class representing a distribution.
Scripts may want to do arbitrary logic based on whichever distro is in use
(e.g. handling differences in names of packages, distribution-specific
patches, etc.)
We can either create methods in the Distro class to handle these, or we
can use constructs like isinstance(distro, Ubuntu) to handle this. We can
even create hierarchies of distro subclasses to handle this kind of thing
(could get messy fast though)
"""
class Fedora(Distro): # pragma: no cover
def __init__(self):
self.packageDb = _RpmPackageDb()
class RHEL(Fedora): # pragma: no cover
pass
class Debian(Distro): # pragma: no cover
def __init__(self):
self.packageDb = _AptPackageDb()
class Ubuntu(Debian):
def __init__(self):
self.packageDb = _UbuntuAptPackageDb()
class Suse(Distro): # pragma: no cover
def __init__(self):
self.packageDb = _RpmPackageDb()
class Gentoo(Distro): # pragma: no cover
def __init__(self):
self.packageDb = _PortagePackageDb()
class Conary(Distro): # pragma: no cover
def __init__(self):
self.packageDb = _ConaryPackageDb()
class Solaris(Distro): # pragma: no cover
def __init__(self):
self.packageDb = _SolarisPackageDb()
class JHBuild(Distro): # pragma: no cover
def __init__(self):
self.packageDb = JhBuildPackageDb()
def detectDistro():
logger.log("Detecting distribution:", newline=False)
if os.environ.get("CERTIFIED_GNOMIE", "no") == "yes":
distro = JHBuild() # pragma: no cover
elif os.path.exists("/etc/SuSE-release"):
distro = Suse() # pragma: no cover
elif os.path.exists("/etc/fedora-release"):
distro = Fedora() # pragma: no cover
elif os.path.exists("/etc/redhat-release"):
distro = RHEL() # pragma: no cover
elif os.path.exists("/usr/share/doc/ubuntu-minimal"):
distro = Ubuntu()
elif os.path.exists("/etc/debian_version"): # pragma: no cover
distro = Debian() # pragma: no cover
elif os.path.exists("/etc/gentoo-release"): # pragma: no cover
distro = Gentoo() # pragma: no cover
elif os.path.exists("/etc/slackware-version"): # pragma: no cover
raise DistributionNotSupportedError("Slackware") # pragma: no cover
elif os.path.exists("/var/lib/conarydb/conarydb"): # pragma: no cover
distro = Conary() # pragma: no cover
elif os.path.exists("/etc/release") and \
re.match(".*Solaris", open("/etc/release").readline()): # pragma: no cover
distro = Solaris() # pragma: no cover
else:
raise DistributionNotSupportedError("Unknown") # pragma: no cover
logger.log(distro.__class__.__name__)
return distro
distro = detectDistro()
packageDb = distro.packageDb
|