Blame dnf/package.py

Packit Service 21c75c
# package.py
Packit Service 21c75c
# Module defining the dnf.Package class.
Packit Service 21c75c
#
Packit Service 21c75c
# Copyright (C) 2012-2016 Red Hat, Inc.
Packit Service 21c75c
#
Packit Service 21c75c
# This copyrighted material is made available to anyone wishing to use,
Packit Service 21c75c
# modify, copy, or redistribute it subject to the terms and conditions of
Packit Service 21c75c
# the GNU General Public License v.2, or (at your option) any later version.
Packit Service 21c75c
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit Service 21c75c
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit Service 21c75c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit Service 21c75c
# Public License for more details.  You should have received a copy of the
Packit Service 21c75c
# GNU General Public License along with this program; if not, write to the
Packit Service 21c75c
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 21c75c
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit Service 21c75c
# source code or documentation are not subject to the GNU General Public
Packit Service 21c75c
# License and may only be used or replicated with the express permission of
Packit Service 21c75c
# Red Hat, Inc.
Packit Service 21c75c
#
Packit Service 21c75c
Packit Service 21c75c
""" Contains the dnf.Package class. """
Packit Service 21c75c
Packit Service 21c75c
from __future__ import absolute_import
Packit Service 21c75c
from __future__ import unicode_literals
Packit Service 21c75c
Packit Service 21c75c
from dnf.i18n import _
Packit Service 21c75c
Packit Service 21c75c
import binascii
Packit Service 21c75c
import dnf.rpm
Packit Service 21c75c
import dnf.yum.misc
Packit Service 21c75c
import hawkey
Packit Service 21c75c
import logging
Packit Service 21c75c
import os
Packit Service 21c75c
Packit Service 21c75c
logger = logging.getLogger("dnf")
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class Package(hawkey.Package):
Packit Service 21c75c
    """ Represents a package. #:api """
Packit Service 21c75c
Packit Service 21c75c
    DEBUGINFO_SUFFIX = "-debuginfo"  # :api
Packit Service 21c75c
    DEBUGSOURCE_SUFFIX = "-debugsource"  # :api
Packit Service 21c75c
Packit Service 21c75c
    def __init__(self, initobject, base):
Packit Service 21c75c
        super(Package, self).__init__(initobject)
Packit Service 21c75c
        self.base = base
Packit Service 21c75c
        self._priv_chksum = None
Packit Service 21c75c
        self._repo = None
Packit Service 21c75c
        self._priv_size = None
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _chksum(self):
Packit Service 21c75c
        if self._priv_chksum:
Packit Service 21c75c
            return self._priv_chksum
Packit Service 21c75c
        if self._from_cmdline:
Packit Service 21c75c
            chksum_type = dnf.yum.misc.get_default_chksum_type()
Packit Service 21c75c
            chksum_val = dnf.yum.misc.checksum(chksum_type, self.location)
Packit Service 21c75c
            return (hawkey.chksum_type(chksum_type),
Packit Service 21c75c
                    binascii.unhexlify(chksum_val))
Packit Service 21c75c
        return super(Package, self).chksum
Packit Service 21c75c
Packit Service 21c75c
    @_chksum.setter
Packit Service 21c75c
    def _chksum(self, val):
Packit Service 21c75c
        self._priv_chksum = val
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _from_cmdline(self):
Packit Service 21c75c
        return self.reponame == hawkey.CMDLINE_REPO_NAME
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _from_system(self):
Packit Service 21c75c
        return self.reponame == hawkey.SYSTEM_REPO_NAME
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _from_repo(self):
Packit Service 21c75c
        pkgrepo = None
Packit Service 21c75c
        if self._from_system:
Packit Service 21c75c
            pkgrepo = self.base.history.repo(self)
Packit Service 21c75c
        else:
Packit Service 21c75c
            pkgrepo = {}
Packit Service 21c75c
        if pkgrepo:
Packit Service 21c75c
            return '@' + pkgrepo
Packit Service 21c75c
        return self.reponame
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _header(self):
Packit Service 21c75c
        return dnf.rpm._header(self.localPkg())
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _size(self):
Packit Service 21c75c
        if self._priv_size:
Packit Service 21c75c
            return self._priv_size
Packit Service 21c75c
        return super(Package, self).size
Packit Service 21c75c
Packit Service 21c75c
    @_size.setter
Packit Service 21c75c
    def _size(self, val):
Packit Service 21c75c
        self._priv_size = val
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _pkgid(self):
Packit Service 21c75c
        if self.hdr_chksum is None:
Packit Service 21c75c
            return None
Packit Service 21c75c
        (_, chksum) = self.hdr_chksum
Packit Service 21c75c
        return binascii.hexlify(chksum)
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def source_name(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        """
Packit Service 21c75c
        returns name of source package
Packit Service 21c75c
        e.g. krb5-libs -> krb5
Packit Service 21c75c
        """
Packit Service 21c75c
        if self.sourcerpm is not None:
Packit Service 21c75c
            # trim suffix first
Packit Service 21c75c
            srcname = dnf.util.rtrim(self.sourcerpm, ".src.rpm")
Packit Service 21c75c
            # sourcerpm should be in form of name-version-release now, so we
Packit Service 21c75c
            # will strip the two rightmost parts separated by dash.
Packit Service 21c75c
            # Using rtrim with version and release of self is not sufficient
Packit Service 21c75c
            # because the package can have different version to the source
Packit Service 21c75c
            # package.
Packit Service 21c75c
            srcname = srcname.rsplit('-', 2)[0]
Packit Service 21c75c
        else:
Packit Service 21c75c
            srcname = None
Packit Service 21c75c
        return srcname
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def debug_name(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        """
Packit Service 21c75c
        Returns name of the debuginfo package for this package.
Packit Service 21c75c
        If this package is a debuginfo package, returns its name.
Packit Service 21c75c
        If this package is a debugsource package, returns the debuginfo package
Packit Service 21c75c
        for the base package.
Packit Service 21c75c
        e.g. kernel-PAE -> kernel-PAE-debuginfo
Packit Service 21c75c
        """
Packit Service 21c75c
        if self.name.endswith(self.DEBUGINFO_SUFFIX):
Packit Service 21c75c
            return self.name
Packit Service 21c75c
Packit Service 21c75c
        name = self.name
Packit Service 21c75c
        if self.name.endswith(self.DEBUGSOURCE_SUFFIX):
Packit Service 21c75c
            name = name[:-len(self.DEBUGSOURCE_SUFFIX)]
Packit Service 21c75c
Packit Service 21c75c
        return name + self.DEBUGINFO_SUFFIX
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def debugsource_name(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        """
Packit Service 21c75c
        Returns name of the debugsource package for this package.
Packit Service 21c75c
        e.g. krb5-libs -> krb5-debugsource
Packit Service 21c75c
        """
Packit Service 21c75c
        # assuming self.source_name is None only for a source package
Packit Service 21c75c
        src_name = self.source_name if self.source_name is not None else self.name
Packit Service 21c75c
        return src_name + self.DEBUGSOURCE_SUFFIX
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def source_debug_name(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        """
Packit Service 21c75c
        returns name of debuginfo package for source package of given package
Packit Service 21c75c
        e.g. krb5-libs -> krb5-debuginfo
Packit Service 21c75c
        """
Packit Service 21c75c
        # assuming self.source_name is None only for a source package
Packit Service 21c75c
        src_name = self.source_name if self.source_name is not None else self.name
Packit Service 21c75c
        return src_name + self.DEBUGINFO_SUFFIX
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def idx(self):
Packit Service 21c75c
        """ Always type it to int, rpm bindings expect it like that. """
Packit Service 21c75c
        return int(self.rpmdbid)
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def repoid(self):
Packit Service 21c75c
        return self.reponame
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def pkgtup(self):
Packit Service 21c75c
        return (self.name, self.arch, str(self.e), self.v, self.r)
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def repo(self):
Packit Service 21c75c
        if self._repo:
Packit Service 21c75c
            return self._repo
Packit Service 21c75c
        return self.base.repos[self.reponame]
Packit Service 21c75c
Packit Service 21c75c
    @repo.setter
Packit Service 21c75c
    def repo(self, val):
Packit Service 21c75c
        self._repo = val
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def reason(self):
Packit Service 21c75c
        if self.repoid != hawkey.SYSTEM_REPO_NAME:
Packit Service 21c75c
            return None
Packit Service 21c75c
        return self.base.history.rpm.get_reason_name(self)
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def relativepath(self):
Packit Service 21c75c
        return self.location
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def a(self):
Packit Service 21c75c
        return self.arch
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def e(self):
Packit Service 21c75c
        return self.epoch
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def v(self):
Packit Service 21c75c
        return self.version
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def r(self):
Packit Service 21c75c
        return self.release
Packit Service 21c75c
Packit Service 21c75c
    @property # yum compatibility attribute
Packit Service 21c75c
    def ui_from_repo(self):
Packit Service 21c75c
        return self.reponame
Packit Service 21c75c
Packit Service 21c75c
    # yum compatibility method
Packit Service 21c75c
    def evr_eq(self, pkg):
Packit Service 21c75c
        return self.evr_cmp(pkg) == 0
Packit Service 21c75c
Packit Service 21c75c
    # yum compatibility method
Packit Service 21c75c
    def evr_gt(self, pkg):
Packit Service 21c75c
        return self.evr_cmp(pkg) > 0
Packit Service 21c75c
Packit Service 21c75c
    # yum compatibility method
Packit Service 21c75c
    def evr_lt(self, pkg):
Packit Service 21c75c
        return self.evr_cmp(pkg) < 0
Packit Service 21c75c
Packit Service 21c75c
    # yum compatibility method
Packit Service 21c75c
    def getDiscNum(self):
Packit Service 21c75c
        return self.medianr
Packit Service 21c75c
Packit Service 21c75c
    # yum compatibility method
Packit Service 21c75c
    def localPkg(self):
Packit Service 21c75c
        """ Package's location in the filesystem.
Packit Service 21c75c
Packit Service 21c75c
            For packages in remote repo returns where the package will be/has
Packit Service 21c75c
            been downloaded.
Packit Service 21c75c
        """
Packit Service 21c75c
        if self._from_cmdline:
Packit Service 21c75c
            return self.location
Packit Service 21c75c
        loc = self.location
Packit Service 21c75c
        if self.repo._repo.isLocal() and self.baseurl and self.baseurl.startswith('file://'):
Packit Service 21c75c
            return os.path.join(self.get_local_baseurl(), loc.lstrip("/"))
Packit Service 21c75c
        if not self._is_local_pkg():
Packit Service 21c75c
            loc = os.path.basename(loc)
Packit Service 21c75c
        return os.path.join(self.pkgdir, loc.lstrip("/"))
Packit Service 21c75c
Packit Service 21c75c
    def remote_location(self, schemes=('http', 'ftp', 'file', 'https')):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        """
Packit Service 21c75c
        The location from where the package can be downloaded from
Packit Service 21c75c
Packit Service 21c75c
        :param schemes: list of allowed protocols. Default is ('http', 'ftp', 'file', 'https')
Packit Service 21c75c
        :return: location (string) or None
Packit Service 21c75c
        """
Packit Service 21c75c
        return self.repo.remote_location(self.location, schemes)
Packit Service 21c75c
Packit Service 21c75c
    def _is_local_pkg(self):
Packit Service 21c75c
        if self.repoid == "@System":
Packit Service 21c75c
            return True
Packit Service 21c75c
        if '://' in self.location and not self.location.startswith('file://'):
Packit Service 21c75c
            # the package has a remote URL as its location
Packit Service 21c75c
            return False
Packit Service 21c75c
        return self._from_cmdline or \
Packit Service 21c75c
            (self.repo._repo.isLocal() and (not self.baseurl or self.baseurl.startswith('file://')))
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def pkgdir(self):
Packit Service 21c75c
        if (self.repo._repo.isLocal() and not self._is_local_pkg()):
Packit Service 21c75c
            return self.repo.cache_pkgdir()
Packit Service 21c75c
        else:
Packit Service 21c75c
            return self.repo.pkgdir
Packit Service 21c75c
Packit Service 21c75c
    # yum compatibility method
Packit Service 21c75c
    def returnIdSum(self):
Packit Service 21c75c
        """ Return the chksum type and chksum string how the legacy yum expects
Packit Service 21c75c
            it.
Packit Service 21c75c
        """
Packit Service 21c75c
        if self._chksum is None:
Packit Service 21c75c
            return (None, None)
Packit Service 21c75c
        (chksum_type, chksum) = self._chksum
Packit Service 21c75c
        return (hawkey.chksum_name(chksum_type), binascii.hexlify(chksum).decode())
Packit Service 21c75c
Packit Service 21c75c
    # yum compatibility method
Packit Service 21c75c
    def verifyLocalPkg(self):
Packit Service 21c75c
        if self._from_system:
Packit Service 21c75c
            raise ValueError("Can not verify an installed package.")
Packit Service 21c75c
        if self._from_cmdline:
Packit Service 21c75c
            return True # local package always verifies against itself
Packit Service 21c75c
        (chksum_type, chksum) = self.returnIdSum()
Packit Service 21c75c
        real_sum = dnf.yum.misc.checksum(chksum_type, self.localPkg(),
Packit Service 21c75c
                                         datasize=self._size)
Packit Service 21c75c
        if real_sum != chksum:
Packit Service 21c75c
            logger.debug(_('%s: %s check failed: %s vs %s'),
Packit Service 21c75c
                         self, chksum_type, real_sum, chksum)
Packit Service 21c75c
            return False
Packit Service 21c75c
        return True