summaryrefslogtreecommitdiffstats
path: root/src/software/openlmi/software/yumdb/packagecheck.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/software/openlmi/software/yumdb/packagecheck.py')
-rw-r--r--src/software/openlmi/software/yumdb/packagecheck.py61
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