diff options
Diffstat (limited to 'src/software/openlmi/software/yumdb/packagecheck.py')
-rw-r--r-- | src/software/openlmi/software/yumdb/packagecheck.py | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/src/software/openlmi/software/yumdb/packagecheck.py b/src/software/openlmi/software/yumdb/packagecheck.py index 4cdc5ee..89852b9 100644 --- a/src/software/openlmi/software/yumdb/packagecheck.py +++ b/src/software/openlmi/software/yumdb/packagecheck.py @@ -26,40 +26,76 @@ Module with definition of RPM package check class. from collections import OrderedDict from datetime import datetime import grp +import logging import os import pwd import rpm import yum +from openlmi.software.yumdb import errors + CHECKSUMTYPE_STR2NUM = dict((val.lower(), k) for (k, val) in yum.constants.RPM_CHECKSUM_TYPES.items()) +( FILE_TYPE_UNKNOWN +, FILE_TYPE_FILE +, FILE_TYPE_DIRECTORY +, FILE_TYPE_SYMLINK +, FILE_TYPE_FIFO +, FILE_TYPE_CHARACTER_DEVICE +, FILE_TYPE_BLOCK_DEVICE +) = range(7) + +FILE_TYPE_NAMES = ( 'unknown', 'file', 'directory', 'symlink', 'fifo' + , 'character device', 'block device') + class PackageFile(object): """ Metadata related to particular file on filesystem belonging to RPM package. Data contained here are from RPM database. + + Attributes: + ``path`` - (``str``) Absolute path of file. + ``file_type`` - (``int``) One of ``FILE_TYPE_*`` identifiers above. + ``uid`` - (``int``) User ID. + ``gid`` - (``int``) Group ID. + ``mode`` - (``int``) Raw file mode. + ``device`` - (``int``) Device number. + ``mtime`` - (``int``) Last modification time in seconds. + ``size`` - (``long``) File size as a number of bytes. + ``link_target`` - (``str``) Link target of symlink. None if ``file_type`` + is not symlink. + ``checksum`` - (``str``) Checksum as string in hexadecimal format. + None if file is not a regular file. """ __slots__ = ("path", "file_type", "uid", "gid", "mode", "device", "mtime", "size", "link_target", "checksum") def __init__(self, path, file_type, uid, gid, mode, device, mtime, size, link_target, checksum): + if not isinstance(file_type, basestring): + raise TypeError("file_type must be a string") for arg in ('uid', 'gid', 'mode', 'mtime', 'size'): if not isinstance(locals()[arg], (int, long)): raise TypeError("%s must be integer" % arg) if not os.path.isabs(path): raise ValueError("path must be an absolute path") self.path = path - self.file_type = file_type.lower() + try: + self.file_type = FILE_TYPE_NAMES.index(file_type.lower()) + except ValueError: + logging.getLogger(__name__).error('unrecognized file type "%s" for' + ' file "%s"', file_type, path) + self.file_type = FILE_TYPE_NAMES[FILE_TYPE_UNKNOWN] self.uid = uid self.gid = gid self.mode = mode - self.device = device if file_type.endswith('device') else None + self.device = device self.mtime = mtime self.size = size self.link_target = (link_target - if file_type == "symlink" and link_target else None) - self.checksum = checksum + if self.file_type == FILE_TYPE_SYMLINK else None) + self.checksum = checksum if self.file_type == FILE_TYPE_FILE else None @property def last_modification_datetime(self): @@ -158,11 +194,15 @@ def pkg_checksum_type(pkg): return pkg.hdr[rpm.RPMTAG_FILEDIGESTALGO] return CHECKSUMTYPE_STR2NUM[pkg.yumdb_info.checksum_type.lower()] -def make_package_check_from_db(vpkg): +def make_package_check_from_db(vpkg, file_name=None): """ Create instance of PackageCheck from instance of - yum.packages._RPMVerifyPackage - @return instance of PackageCheck + yum.packages._RPMVerifyPackage. + + :param file_name: (``str``) If not None, causes result to have just + one instance of ``PackageFile`` matching this file_name. + If it's not found in the package, ``FileNotFound`` will be raised. + :rtype (``PackageCheck``) """ if not isinstance(vpkg, yum.packages._RPMVerifyPackage): raise TypeError("vpkg must be instance of" @@ -172,6 +212,8 @@ def make_package_check_from_db(vpkg): res = PackageCheck(id(pkg), pkg_checksum_type(pkg)) files = res.files for vpf in vpkg: + if file_name is not None and file_name != vpf.filename: + continue files[vpf.filename] = PackageFile( vpf.filename, vpf.ftype, @@ -184,5 +226,10 @@ def make_package_check_from_db(vpkg): vpf.readlink, vpf.digest[1] ) + if file_name is not None: + break + if file_name is not None and len(files) < 1: + raise errors.FileNotFound('File "%s" not found in package "%s".' % ( + file_name, pkg.nevra)) return res |