Back to index

apport  2.4
Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions | Private Attributes
packaging_rpm.RPMPackageInfo Class Reference

List of all members.

Public Member Functions

def __init__
def get_version
def get_available_version
def get_dependencies
def get_source
def get_architecture
def get_files
def get_modified_files
def get_file_package
def get_system_architecture
def is_distro_package
def set_mirror
def get_source_tree
def compare_versions
def package_name_glob

Public Attributes

 ts

Static Public Attributes

tuple official_keylist = ()

Private Member Functions

def _get_headers_by_tag
def _get_header
def _make_envra_from_header
def _checkmd5

Private Attributes

 _mirror

Detailed Description

Partial apport.PackageInfo class implementation for RPM, as
found in Fedora, RHEL, CentOS, etc.

Definition at line 30 of file packaging_rpm.py.


Constructor & Destructor Documentation

Definition at line 38 of file packaging_rpm.py.

00038 
00039     def __init__(self):
00040         self.ts = rpm.TransactionSet()  # connect to the rpmdb
00041         self._mirror = None


Member Function Documentation

def packaging_rpm.RPMPackageInfo._checkmd5 (   self,
  filename,
  filemd5 
) [private]
Internal function to check a file's md5sum

Definition at line 255 of file packaging_rpm.py.

00255 
00256     def _checkmd5(self, filename, filemd5):
00257         '''Internal function to check a file's md5sum'''
00258 
00259         m = hashlib.md5()
00260         f = open(filename)
00261         data = f.read()
00262         f.close()
00263         m.update(data)
00264         return (filemd5 == m.hexdigest())

Here is the caller graph for this function:

def packaging_rpm.RPMPackageInfo._get_header (   self,
  envra 
) [private]
Get the RPM header that matches the given ENVRA.

Definition at line 221 of file packaging_rpm.py.

00221 
00222     def _get_header(self, envra):
00223         '''Get the RPM header that matches the given ENVRA.'''
00224 
00225         querystr = envra
00226         qlen = len(envra)
00227         while qlen > 0:
00228             mi = impl.ts.dbMatch('name', querystr)
00229             hdrs = [m for m in mi]
00230             if len(hdrs) > 0:
00231                 # yay! we found something
00232                 # Unless there's some rpmdb breakage, you should have one header
00233                 # here. If you do manage to have two rpms with the same ENVRA,
00234                 # who cares which one you get?
00235                 h = hdrs[0]
00236                 break
00237 
00238             # remove the last char of querystr and retry the search
00239             querystr = querystr[0:len(querystr) - 1]
00240             qlen = qlen - 1
00241 
00242         if qlen == 0:
00243             raise ValueError('No headers found for this envra: %s' % envra)
00244         return h

Here is the caller graph for this function:

def packaging_rpm.RPMPackageInfo._get_headers_by_tag (   self,
  tag,
  arg 
) [private]
Get a list of RPM headers by doing dbMatch on the given tag and
argument.

Definition at line 213 of file packaging_rpm.py.

00213 
00214     def _get_headers_by_tag(self, tag, arg):
00215         '''Get a list of RPM headers by doing dbMatch on the given tag and
00216         argument.'''
00217         matches = self.ts.dbMatch(tag, arg)
00218         if matches.count() == 0:
00219             raise ValueError('Could not find package with %s: %s' % (tag, arg))
00220         return [m for m in matches]

Here is the caller graph for this function:

def packaging_rpm.RPMPackageInfo._make_envra_from_header (   self,
  h 
) [private]
Generate an ENVRA string from an rpm header

Definition at line 245 of file packaging_rpm.py.

00245 
00246     def _make_envra_from_header(self, h):
00247         '''Generate an ENVRA string from an rpm header'''
00248 
00249         nvra = "%s-%s-%s.%s" % (h['n'], h['v'], h['r'], h['arch'])
00250         if h['e']:
00251             envra = "%s:%s" % (h['e'], nvra)
00252         else:
00253             envra = nvra
00254         return envra

Here is the caller graph for this function:

def packaging_rpm.RPMPackageInfo.compare_versions (   self,
  ver1,
  ver2 
)
Compare two package versions.

Return -1 for ver < ver2, 0 for ver1 == ver2, and 1 for ver1 > ver2.

Definition at line 192 of file packaging_rpm.py.

00192 
00193     def compare_versions(self, ver1, ver2):
00194         '''Compare two package versions.
00195 
00196         Return -1 for ver < ver2, 0 for ver1 == ver2, and 1 for ver1 > ver2.'''
00197         # Used by crashdb.py (i.e. the frontends)
00198         # I could duplicate stringToVersion/compareEVR from rpmUtils.misc,
00199         # but I hate duplicating code. So if you don't want to require rpmUtils
00200         # you can implement this function yourself. Probably you've got
00201         # equivalent code in whatever your distro uses instead of yum anyway.
00202         raise NotImplementedError('method must be implemented by distro-specific RPMPackageInfo subclass')

def packaging_rpm.RPMPackageInfo.get_architecture (   self,
  package 
)
Return the architecture of a package.

This might differ on multiarch architectures (e. g.  an i386 Firefox
package on a x86_64 system)

Definition at line 83 of file packaging_rpm.py.

00083 
00084     def get_architecture(self, package):
00085         '''Return the architecture of a package.
00086 
00087         This might differ on multiarch architectures (e. g.  an i386 Firefox
00088         package on a x86_64 system)'''
00089         # Yeah, this is kind of redundant, as package is ENVRA, but I want
00090         # to do this the right way (in case we change what 'package' is)
00091         hdr = self._get_header(package)
00092         return hdr['arch']

Here is the call graph for this function:

Return the latest available version of a package.

Definition at line 55 of file packaging_rpm.py.

00055 
00056     def get_available_version(self, package):
00057         '''Return the latest available version of a package.'''
00058         # used in report.py, which is used by the frontends
00059         raise NotImplementedError('method must be implemented by distro-specific RPMPackageInfo subclass')

def packaging_rpm.RPMPackageInfo.get_dependencies (   self,
  package 
)
Return a list of packages a package depends on.

Definition at line 60 of file packaging_rpm.py.

00060 
00061     def get_dependencies(self, package):
00062         '''Return a list of packages a package depends on.'''
00063         hdr = self._get_header(package)
00064         # parse this package's Requires
00065         reqs = []
00066         for r in hdr['requires']:
00067             if r.startswith('rpmlib') or r.startswith('uname('):
00068                 continue  # we've got rpmlib, thanks
00069             if r[0] == '/':  # file requires
00070                 req_heads = self._get_headers_by_tag('basenames', r)
00071             else:           # other requires
00072                 req_heads = self._get_headers_by_tag('provides', r)
00073             for rh in req_heads:
00074                 rh_envra = self._make_envra_from_header(rh)
00075                 if rh_envra not in reqs:
00076                     reqs.append(rh_envra)
00077         return reqs

Here is the call graph for this function:

Return the package a file belongs to, or None if the file is not
shipped by any package.

Under normal use, the 'file' argument will always be the executable
that crashed.

Definition at line 131 of file packaging_rpm.py.

00131 
00132     def get_file_package(self, file):
00133         '''Return the package a file belongs to, or None if the file is not
00134         shipped by any package.
00135 
00136         Under normal use, the 'file' argument will always be the executable
00137         that crashed.
00138         '''
00139         # The policy for handling files which belong to multiple packages depends on the distro
00140         raise NotImplementedError('method must be implemented by distro-specific RPMPackageInfo subclass')

def packaging_rpm.RPMPackageInfo.get_files (   self,
  package 
)
Return list of files shipped by a package.

Definition at line 93 of file packaging_rpm.py.

00093 
00094     def get_files(self, package):
00095         '''Return list of files shipped by a package.'''
00096         hdr = self._get_header(package)
00097         files = []
00098         for (f, mode) in zip(hdr['filenames'], hdr['filemodes']):
00099             if not stat.S_ISDIR(mode):
00100                 files.append(f)
00101         return files

Here is the call graph for this function:

def packaging_rpm.RPMPackageInfo.get_modified_files (   self,
  package 
)
Return list of all modified files of a package.

Definition at line 102 of file packaging_rpm.py.

00102 
00103     def get_modified_files(self, package):
00104         '''Return list of all modified files of a package.'''
00105         hdr = self._get_header(package)
00106 
00107         files = hdr['filenames']
00108         mtimes = hdr['filemtimes']
00109         md5s = hdr['filemd5s']
00110 
00111         modified = []
00112         for i in xrange(len(files)):
00113             # Skip files we're not tracking md5s for
00114             if not md5s[i]:
00115                 continue
00116             # Skip files we can't read
00117             if not os.access(files[i], os.R_OK):
00118                 continue
00119             # Skip things that aren't real files
00120             s = os.stat(files[i])
00121             if not stat.S_ISREG(s.st_mode):
00122                 continue
00123             # Skip things that haven't been modified
00124             if mtimes[i] == s.st_mtime:
00125                 continue
00126             # Oh boy, an actual possibly-modified file. Check the md5sum!
00127             if not self._checkmd5(files[i], md5s[i]):
00128                 modified.append(files[i])
00129 
00130         return modified

Here is the call graph for this function:

def packaging_rpm.RPMPackageInfo.get_source (   self,
  package 
)
Return the source package name for a package.

Definition at line 78 of file packaging_rpm.py.

00078 
00079     def get_source(self, package):
00080         '''Return the source package name for a package.'''
00081         hdr = self._get_header(package)
00082         return hdr['sourcerpm']

Here is the call graph for this function:

def packaging_rpm.RPMPackageInfo.get_source_tree (   self,
  srcpackage,
  dir,
  version = None 
)
Download given source package and unpack it into dir (which should
be empty).

This also has to care about applying patches etc., so that dir will
eventually contain the actually compiled source.

If version is given, this particular version will be retrieved.
Otherwise this will fetch the latest available version.

Return the directory that contains the actual source root directory
(which might be a subdirectory of dir). Return None if the source is
not available.

Definition at line 176 of file packaging_rpm.py.

00176 
00177     def get_source_tree(self, srcpackage, dir, version=None):
00178         '''Download given source package and unpack it into dir (which should
00179         be empty).
00180 
00181         This also has to care about applying patches etc., so that dir will
00182         eventually contain the actually compiled source.
00183 
00184         If version is given, this particular version will be retrieved.
00185         Otherwise this will fetch the latest available version.
00186 
00187         Return the directory that contains the actual source root directory
00188         (which might be a subdirectory of dir). Return None if the source is
00189         not available.'''
00190         # Used only by apport-retrace.
00191         raise NotImplementedError('method must be implemented by distro-specific RPMPackageInfo subclass')

Return the architecture of the system, in the notation used by the
particular distribution.

Definition at line 141 of file packaging_rpm.py.

00141 
00142     def get_system_architecture(self):
00143         '''Return the architecture of the system, in the notation used by the
00144         particular distribution.'''
00145         rpmarch = subprocess.Popen(['rpm', '--eval', '%_target_cpu'],
00146                                    stdout=subprocess.PIPE)
00147         arch = rpmarch.communicate()[0].strip()
00148         return arch

def packaging_rpm.RPMPackageInfo.get_version (   self,
  package 
)
Return the installed version of a package.

Definition at line 42 of file packaging_rpm.py.

00042 
00043     def get_version(self, package):
00044         '''Return the installed version of a package.'''
00045         hdr = self._get_header(package)
00046         if hdr is None:
00047             raise ValueError
00048         # Note - "version" here seems to refer to the full EVR, so..
00049         if not hdr['e']:
00050             return hdr['v'] + '-' + hdr['r']
00051         if not hdr['v'] or not hdr['r']:
00052             return None
00053         else:
00054             return hdr['e'] + ':' + hdr['v'] + '-' + hdr['r']

Here is the call graph for this function:

def packaging_rpm.RPMPackageInfo.is_distro_package (   self,
  package 
)
Check if a package is a genuine distro package (True) or comes from
a third-party source.

Definition at line 149 of file packaging_rpm.py.

00149 
00150     def is_distro_package(self, package):
00151         '''Check if a package is a genuine distro package (True) or comes from
00152         a third-party source.'''
00153         # This is a list of official keys, set by the concrete subclass
00154         if not self.official_keylist:
00155             raise Exception('Subclass the RPM implementation for your distro!')
00156         hdr = self._get_header(package)
00157         if not hdr:
00158             return False
00159         # Check the GPG sig and key ID to see if this package was signed
00160         # with an official key.
00161         if hdr['siggpg']:
00162             # Package is signed
00163             keyid = hdr['siggpg'][13:17].encode('hex')
00164             if keyid in self.official_keylist:
00165                 return True
00166         return False

Here is the call graph for this function:

Return known package names which match given glob.

Definition at line 203 of file packaging_rpm.py.

00203 
00204     def package_name_glob(self, glob):
00205         '''Return known package names which match given glob.'''
00206 
00207         raise NotImplementedError('TODO')

def packaging_rpm.RPMPackageInfo.set_mirror (   self,
  url 
)
Explicitly set a distribution mirror URL for operations that need to
fetch distribution files/packages from the network.

By default, the mirror will be read from the system configuration
files.

Definition at line 167 of file packaging_rpm.py.

00167 
00168     def set_mirror(self, url):
00169         '''Explicitly set a distribution mirror URL for operations that need to
00170         fetch distribution files/packages from the network.
00171 
00172         By default, the mirror will be read from the system configuration
00173         files.'''
00174         # FIXME C&P from apt-dpkg implementation, might move to subclass
00175         self._mirror = url


Member Data Documentation

Definition at line 40 of file packaging_rpm.py.

Definition at line 36 of file packaging_rpm.py.

Definition at line 39 of file packaging_rpm.py.


The documentation for this class was generated from the following file: