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.py188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/software/openlmi/software/yumdb/packagecheck.py b/src/software/openlmi/software/yumdb/packagecheck.py
new file mode 100644
index 0000000..fbb5b21
--- /dev/null
+++ b/src/software/openlmi/software/yumdb/packagecheck.py
@@ -0,0 +1,188 @@
+# -*- encoding: utf-8 -*-
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+#
+"""
+Module with definition of RPM package check class.
+"""
+
+from collections import OrderedDict
+from datetime import datetime
+import grp
+import os
+import pwd
+import rpm
+import yum
+
+CHECKSUMTYPE_STR2NUM = dict((val.lower(), k) for (k, val) in
+ yum.constants.RPM_CHECKSUM_TYPES.items())
+
+class PackageFile(object):
+ """
+ Metadata related to particular file on filesystem belonging to RPM package.
+ Data contained here are from RPM database.
+ """
+ __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):
+ 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()
+ self.uid = uid
+ self.gid = gid
+ self.mode = mode
+ self.device = device if file_type.endswith('device') else None
+ self.mtime = mtime
+ self.size = size
+ self.link_target = (link_target
+ if file_type == "symlink" and link_target else None)
+ self.checksum = checksum
+
+ @property
+ def last_modification_datetime(self):
+ """
+ @return instance datetime for last modification time of file
+ """
+ return datetime.fromtimestamp(self.mtime)
+
+ def __getstate__(self):
+ """
+ Used for serialization with pickle.
+ @return container content that will be serialized
+ """
+ return dict((k, getattr(self, k)) for k in self.__slots__)
+
+ def __setstate__(self, state):
+ """
+ Used for deserialization with pickle.
+ Restores the object from serialized form.
+ @param state is an object created by __setstate__() method
+ """
+ for k, value in state.items():
+ setattr(self, k, value)
+
+class PackageCheck(object):
+ """
+ Metadata for package concerning verification.
+ It contains metadata for each file installed in "files" attribute.
+ """
+ __slots__ = ("pkgid", "file_checksum_type", "files")
+
+ def __init__(self, pkgid, file_checksum_type, files=None):
+ """
+ @param pkgid is an in of original yum package object, which is used
+ by server for subsequent operations on this package requested by client
+ """
+ if files is not None and not isinstance(
+ files, (list, tuple, set, dict)):
+ raise TypeError("files must be an iterable container")
+ self.pkgid = pkgid
+ self.file_checksum_type = file_checksum_type
+ if not isinstance(files, dict):
+ self.files = OrderedDict()
+ if files is not None:
+ for file_check in sorted(files, key=lambda f: f.path):
+ self.files[file_check.path] = file_check
+ else:
+ for path in sorted(files):
+ self.files[path] = files[path]
+
+ def __iter__(self):
+ return iter(self.files)
+
+ def __len__(self):
+ return len(self.files)
+
+ def __getitem__(self, filepath):
+ return self.files[filepath]
+
+ def __setitem__(self, filepath, package_file):
+ if not isinstance(package_file, PackageFile):
+ raise TypeError("package_file must be a PackageFile instance")
+ self.files[filepath] = package_file
+
+ def __contains__(self, fileobj):
+ if isinstance(fileobj, basestring):
+ return fileobj in self.files
+ elif isinstance(fileobj, PackageFile):
+ return fileobj.path in self.files
+ else:
+ raise TypeError("expected file path for argument")
+
+ def __getstate__(self):
+ """
+ Used for serialization with pickle.
+ @return container content that will be serialized
+ """
+ return dict((k, getattr(self, k)) for k in self.__slots__)
+
+ def __setstate__(self, state):
+ """
+ Used for deserialization with pickle.
+ Restores the object from serialized form.
+ @param state is an object created by __setstate__() method
+ """
+ for k, value in state.items():
+ setattr(self, k, value)
+
+def pkg_checksum_type(pkg):
+ """
+ @return integer representation of checksum type
+ """
+ if not isinstance(pkg, yum.packages.YumAvailablePackage):
+ raise TypeError("pkg must be an instance of YumAvailablePackage")
+ if isinstance(pkg, yum.rpmsack.RPMInstalledPackage):
+ return pkg.hdr[rpm.RPMTAG_FILEDIGESTALGO]
+ return CHECKSUMTYPE_STR2NUM[pkg.yumdb_info.checksum_type.lower()]
+
+def make_package_check_from_db(vpkg):
+ """
+ Create instance of PackageCheck from instance of
+ yum.packages._RPMVerifyPackage
+ @return instance of PackageCheck
+ """
+ if not isinstance(vpkg, yum.packages._RPMVerifyPackage):
+ raise TypeError("vpkg must be instance of"
+ " yum.packages._RPMVerifyPackage")
+ pkg = vpkg.po
+
+ res = PackageCheck(id(pkg), pkg_checksum_type(pkg))
+ files = res.files
+ for vpf in vpkg:
+ files[vpf.filename] = PackageFile(
+ vpf.filename,
+ vpf.ftype,
+ pwd.getpwnam(vpf.user).pw_uid,
+ grp.getgrnam(vpf.group).gr_gid,
+ vpf.mode,
+ vpf.dev,
+ vpf.mtime,
+ vpf.size,
+ vpf.readlink,
+ vpf.digest[1]
+ )
+ return res
+