diff options
Diffstat (limited to 'src/software/openlmi/software/yumdb/packageinfo.py')
-rw-r--r-- | src/software/openlmi/software/yumdb/packageinfo.py | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/software/openlmi/software/yumdb/packageinfo.py b/src/software/openlmi/software/yumdb/packageinfo.py new file mode 100644 index 0000000..b2cd2b8 --- /dev/null +++ b/src/software/openlmi/software/yumdb/packageinfo.py @@ -0,0 +1,171 @@ +# -*- 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 holding an abstraction for RPM package. +""" + +from datetime import datetime +import yum + +from openlmi.software import util + +class PackageInfo(object): + """ + Container for package metadata. It represents rpm package in yum + database. It's supposed to be passed from YumWorker to YumDB client + and vice-versa. Instances of YumAvailablePackage can not be exchanged + -- results in segfaults. + + To speed up looking up of original yum package object on server, an + atribute "pkgid" is provided. + """ + __slots__ = ( + "pkgid", + "name", "epoch", "version", "release", "architecture", + 'summary', 'description', 'license', 'group', 'vendor', + 'size', + 'installed', # boolean + 'install_time' # datetime instance + ) + + def __init__(self, pkgid, name, epoch, version, release, arch, **kwargs): + """ + @param pkgid is an in of original yum package object, which is used + by server for subsequent operations on this package requested by client + """ + self.pkgid = pkgid + self.name = name + self.epoch = epoch + self.version = version + self.release = release + self.architecture = arch + self.summary = kwargs.pop('summary', None) + self.description = kwargs.pop('description', None) + self.license = kwargs.pop('license', None) + self.group = kwargs.pop('group', None) + self.vendor = kwargs.pop('vendor', None) + self.size = kwargs.pop('size', None) + if self.size is not None and not isinstance(self.size, (int, long)): + raise TypeError('size must be an integer') + self.installed = kwargs.pop('installed', None) + if self.installed is not None: + self.installed = bool(self.installed) + self.install_time = kwargs.pop('install_time', None) + if ( self.install_time is not None + and not isinstance(self.install_time, datetime)): + raise TypeError('install_time must be a datetime') + + # ************************************************************************* + # Properties + # ************************************************************************* + @property + def ver(self): + """Shortcut for version property.""" + return self.version + + @property + def rel(self): + """Shortcut for release property.""" + return self.release + + @property + def arch(self): + """Shortcut for architecture property.""" + return self.architecture + + @property + def nevra(self): + """@return nevra of package with epoch always present.""" + return self.get_nevra(with_epoch="ALWAYS") + + @property + def evra(self): + """@return evra of package.""" + return "%s:%s-%s.%s" % ( + self.epoch if self.epoch and self.epoch != "(none)" else "0", + self.version, + self.release, + self.architecture) + + @property + def key_props(self): + """ + @return package properties as dictionary, + that uniquelly identify package in database + """ + return dict((k, getattr(self, k)) for k in ( + 'name', 'epoch', 'version', 'release', 'arch')) + + # ************************************************************************* + # Public methods + # ************************************************************************* + def get_nevra(self, with_epoch='NOT_ZERO'): + """ + @param with_epoch may be one of: + "NOT_ZERO" - include epoch only if it's not zero + "ALWAYS" - include epoch always + "NEVER" - do not include epoch at all + @return nevra of package + """ + return util.make_nevra(self.name, self.epoch, self.version, + self.release, self.arch, with_epoch) + + # ************************************************************************* + # Special methods + # ************************************************************************* + def __str__(self): + return self.nevra + + 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 make_package_from_db(pkg): + """ + Create instance of PackageInfo from instance of + yum.packages.YumAvailablePackage. + @return instance of PackageInfo + """ + metadata = dict((k, getattr(pkg, k)) for k in ( + 'summary', 'description', 'license', 'group', 'vendor', + 'size')) + if isinstance(pkg, yum.rpmsack.RPMInstalledPackage): + metadata['installed'] = True + metadata['install_time'] = datetime.fromtimestamp(pkg.installtime) + else: + metadata['installed'] = False + res = PackageInfo(id(pkg), pkg.name, pkg.epoch, pkg.version, pkg.release, + pkg.arch, **metadata) + return res + |