Blame dnf/repo.py

Packit 6f3914
# repo.py
Packit 6f3914
# DNF Repository objects.
Packit 6f3914
#
Packit 6f3914
# Copyright (C) 2013-2016 Red Hat, Inc.
Packit 6f3914
#
Packit 6f3914
# This copyrighted material is made available to anyone wishing to use,
Packit 6f3914
# modify, copy, or redistribute it subject to the terms and conditions of
Packit 6f3914
# the GNU General Public License v.2, or (at your option) any later version.
Packit 6f3914
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit 6f3914
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit 6f3914
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 6f3914
# Public License for more details.  You should have received a copy of the
Packit 6f3914
# GNU General Public License along with this program; if not, write to the
Packit 6f3914
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6f3914
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit 6f3914
# source code or documentation are not subject to the GNU General Public
Packit 6f3914
# License and may only be used or replicated with the express permission of
Packit 6f3914
# Red Hat, Inc.
Packit 6f3914
#
Packit 6f3914
Packit 6f3914
from __future__ import absolute_import
Packit 6f3914
from __future__ import unicode_literals
Packit 6f3914
Packit 6f3914
from dnf.i18n import ucd, _
Packit 6f3914
Packit 6f3914
import dnf.callback
Packit 6f3914
import dnf.conf
Packit 6f3914
import dnf.conf.substitutions
Packit 6f3914
import dnf.const
Packit 6f3914
import dnf.crypto
Packit 6f3914
import dnf.exceptions
Packit 6f3914
import dnf.logging
Packit 6f3914
import dnf.pycomp
Packit 6f3914
import dnf.util
Packit 6f3914
import dnf.yum.misc
Packit 6f3914
import libdnf.repo
Packit 6f3914
import functools
Packit 6f3914
import hashlib
Packit 6f3914
import hawkey
Packit 6f3914
import logging
Packit 6f3914
import operator
Packit 6f3914
import os
Packit 6f3914
import re
Packit 6f3914
import shutil
Packit 6f3914
import string
Packit 6f3914
import sys
Packit 6f3914
import time
Packit 6f3914
import traceback
Packit 6f3914
Packit 6f3914
_PACKAGES_RELATIVE_DIR = "packages"
Packit 6f3914
_MIRRORLIST_FILENAME = "mirrorlist"
Packit 6f3914
# Chars allowed in a repo ID
Packit 6f3914
_REPOID_CHARS = string.ascii_letters + string.digits + '-_.:'
Packit 6f3914
# Regex pattern that matches a repo cachedir and captures the repo ID
Packit 6f3914
_CACHEDIR_RE = r'(?P<repoid>[%s]+)\-[%s]{16}' % (re.escape(_REPOID_CHARS),
Packit 6f3914
                                                 string.hexdigits)
Packit 6f3914
Packit 6f3914
# Regex patterns matching any filename that is repo-specific cache data of a
Packit 6f3914
# particular type.  The filename is expected to not contain the base cachedir
Packit 6f3914
# path components.
Packit 6f3914
CACHE_FILES = {
Packit 6f3914
    'metadata': r'^%s\/.*(xml(\.gz|\.xz|\.bz2|.zck)?|asc|cachecookie|%s)$' %
Packit 6f3914
                (_CACHEDIR_RE, _MIRRORLIST_FILENAME),
Packit 6f3914
    'packages': r'^%s\/%s\/.+rpm$' % (_CACHEDIR_RE, _PACKAGES_RELATIVE_DIR),
Packit 6f3914
    'dbcache': r'^.+(solv|solvx)$',
Packit 6f3914
}
Packit 6f3914
Packit 6f3914
logger = logging.getLogger("dnf")
Packit 6f3914
Packit 6f3914
Packit 6f3914
def repo_id_invalid(repo_id):
Packit 6f3914
    # :api
Packit 6f3914
    """Return index of an invalid character in the repo ID (if present)."""
Packit 6f3914
    first_invalid = libdnf.repo.Repo.verifyId(repo_id)
Packit 6f3914
    return None if first_invalid < 0 else first_invalid
Packit 6f3914
Packit 6f3914
Packit 6f3914
def _pkg2payload(pkg, progress, *factories):
Packit 6f3914
    for fn in factories:
Packit 6f3914
        pload = fn(pkg, progress)
Packit 6f3914
        if pload is not None:
Packit 6f3914
            return pload
Packit 6f3914
    raise ValueError(_('no matching payload factory for %s') % pkg)
Packit 6f3914
Packit 6f3914
Packit 6f3914
def _download_payloads(payloads, drpm):
Packit 6f3914
    # download packages
Packit 6f3914
    def _download_sort_key(payload):
Packit 6f3914
        return not hasattr(payload, 'delta')
Packit 6f3914
Packit 6f3914
    drpm.err.clear()
Packit 6f3914
    targets = [pload._librepo_target()
Packit 6f3914
               for pload in sorted(payloads, key=_download_sort_key)]
Packit 6f3914
    errs = _DownloadErrors()
Packit 6f3914
    try:
Packit 6f3914
        libdnf.repo.PackageTarget.downloadPackages(libdnf.repo.VectorPPackageTarget(targets), True)
Packit 6f3914
    except RuntimeError as e:
Packit 6f3914
        errs._fatal = str(e)
Packit 6f3914
    drpm.wait()
Packit 6f3914
Packit 6f3914
    # process downloading errors
Packit 6f3914
    errs._recoverable = drpm.err.copy()
Packit 6f3914
    for tgt in targets:
Packit 6f3914
        err = tgt.getErr()
Packit 6f3914
        if err is None or err.startswith('Not finished'):
Packit 6f3914
            continue
Packit 6f3914
        callbacks = tgt.getCallbacks()
Packit 6f3914
        payload = callbacks.package_pload
Packit 6f3914
        pkg = payload.pkg
Packit 6f3914
        if err == _('Already downloaded'):
Packit 6f3914
            errs._skipped.add(pkg)
Packit 6f3914
            continue
Packit 6f3914
        pkg.repo._repo.expire()
Packit 6f3914
        errs._irrecoverable[pkg] = [err]
Packit 6f3914
Packit 6f3914
    return errs
Packit 6f3914
Packit 6f3914
Packit 6f3914
def _update_saving(saving, payloads, errs):
Packit 6f3914
    real, full = saving
Packit 6f3914
    for pload in payloads:
Packit 6f3914
        pkg = pload.pkg
Packit 6f3914
        if pkg in errs:
Packit 6f3914
            real += pload.download_size
Packit 6f3914
            continue
Packit 6f3914
        real += pload.download_size
Packit 6f3914
        full += pload._full_size
Packit 6f3914
    return real, full
Packit 6f3914
Packit 6f3914
Packit 6f3914
class _DownloadErrors(object):
Packit 6f3914
    def __init__(self):
Packit 6f3914
        self._val_irrecoverable = {}
Packit 6f3914
        self._val_recoverable = {}
Packit 6f3914
        self._fatal = None
Packit 6f3914
        self._skipped = set()
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def _irrecoverable(self):
Packit 6f3914
        if self._val_irrecoverable:
Packit 6f3914
            return self._val_irrecoverable
Packit 6f3914
        if self._fatal:
Packit 6f3914
            return {'': [self._fatal]}
Packit 6f3914
        return {}
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def _recoverable(self):
Packit 6f3914
        return self._val_recoverable
Packit 6f3914
Packit 6f3914
    @_recoverable.setter
Packit 6f3914
    def _recoverable(self, new_dct):
Packit 6f3914
        self._val_recoverable = new_dct
Packit 6f3914
Packit 6f3914
    def _bandwidth_used(self, pload):
Packit 6f3914
        if pload.pkg in self._skipped:
Packit 6f3914
            return 0
Packit 6f3914
        return pload.download_size
Packit 6f3914
Packit 6f3914
Packit 6f3914
class _DetailedLibrepoError(Exception):
Packit 6f3914
    def __init__(self, librepo_err, source_url):
Packit 6f3914
        Exception.__init__(self)
Packit 6f3914
        self.librepo_code = librepo_err.args[0]
Packit 6f3914
        self.librepo_msg = librepo_err.args[1]
Packit 6f3914
        self.source_url = source_url
Packit 6f3914
Packit 6f3914
Packit 6f3914
class _NullKeyImport(dnf.callback.KeyImport):
Packit 6f3914
    def _confirm(self, id, userid, fingerprint, url, timestamp):
Packit 6f3914
        return True
Packit 6f3914
Packit 6f3914
Packit 6f3914
class Metadata(object):
Packit 6f3914
    def __init__(self, repo):
Packit 6f3914
        self._repo = repo
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def fresh(self):
Packit 6f3914
        # :api
Packit 6f3914
        return self._repo.fresh()
Packit 6f3914
Packit 6f3914
Packit 6f3914
class PackageTargetCallbacks(libdnf.repo.PackageTargetCB):
Packit 6f3914
    def __init__(self, package_pload):
Packit 6f3914
        super(PackageTargetCallbacks, self).__init__()
Packit 6f3914
        self.package_pload = package_pload
Packit 6f3914
Packit 6f3914
    def end(self, status, msg):
Packit 6f3914
        self.package_pload._end_cb(None, status, msg)
Packit 6f3914
        return 0
Packit 6f3914
Packit 6f3914
    def progress(self, totalToDownload, downloaded):
Packit 6f3914
        self.package_pload._progress_cb(None, totalToDownload, downloaded)
Packit 6f3914
        return 0
Packit 6f3914
Packit 6f3914
    def mirrorFailure(self, msg, url):
Packit 6f3914
        self.package_pload._mirrorfail_cb(None, msg, url)
Packit 6f3914
        return 0
Packit 6f3914
Packit 6f3914
Packit 6f3914
class PackagePayload(dnf.callback.Payload):
Packit 6f3914
    def __init__(self, pkg, progress):
Packit 6f3914
        super(PackagePayload, self).__init__(progress)
Packit 6f3914
        self.callbacks = PackageTargetCallbacks(self)
Packit 6f3914
        self.pkg = pkg
Packit 6f3914
Packit 6f3914
    def _end_cb(self, cbdata, lr_status, msg):
Packit 6f3914
        """End callback to librepo operation."""
Packit 6f3914
        status = dnf.callback.STATUS_FAILED
Packit 6f3914
        if msg is None:
Packit 6f3914
            status = dnf.callback.STATUS_OK
Packit 6f3914
        elif msg.startswith('Not finished'):
Packit 6f3914
            return
Packit 6f3914
        elif lr_status == libdnf.repo.PackageTargetCB.TransferStatus_ALREADYEXISTS:
Packit 6f3914
            status = dnf.callback.STATUS_ALREADY_EXISTS
Packit 6f3914
Packit 6f3914
        self.progress.end(self, status, msg)
Packit 6f3914
Packit 6f3914
    def _mirrorfail_cb(self, cbdata, err, url):
Packit 6f3914
        self.progress.end(self, dnf.callback.STATUS_MIRROR, err)
Packit 6f3914
Packit 6f3914
    def _progress_cb(self, cbdata, total, done):
Packit 6f3914
        try:
Packit 6f3914
            self.progress.progress(self, done)
Packit 6f3914
        except Exception:
Packit 6f3914
            exc_type, exc_value, exc_traceback = sys.exc_info()
Packit 6f3914
            except_list = traceback.format_exception(exc_type, exc_value, exc_traceback)
Packit 6f3914
            logger.critical(''.join(except_list))
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def _full_size(self):
Packit 6f3914
        return self.download_size
Packit 6f3914
Packit 6f3914
    def _librepo_target(self):
Packit 6f3914
        pkg = self.pkg
Packit 6f3914
        pkgdir = pkg.pkgdir
Packit 6f3914
        dnf.util.ensure_dir(pkgdir)
Packit 6f3914
Packit 6f3914
        target_dct = {
Packit 6f3914
            'dest': pkgdir,
Packit 6f3914
            'resume': True,
Packit 6f3914
            'cbdata': self,
Packit 6f3914
            'progresscb': self._progress_cb,
Packit 6f3914
            'endcb': self._end_cb,
Packit 6f3914
            'mirrorfailurecb': self._mirrorfail_cb,
Packit 6f3914
        }
Packit 6f3914
        target_dct.update(self._target_params())
Packit 6f3914
Packit 6f3914
        return libdnf.repo.PackageTarget(
Packit 6f3914
            pkg.repo._repo,
Packit 6f3914
            target_dct['relative_url'],
Packit 6f3914
            target_dct['dest'], target_dct['checksum_type'], target_dct['checksum'],
Packit 6f3914
            target_dct['expectedsize'], target_dct['base_url'], target_dct['resume'],
Packit 6f3914
            0, 0, self.callbacks)
Packit 6f3914
Packit 6f3914
Packit 6f3914
class RPMPayload(PackagePayload):
Packit 6f3914
Packit 6f3914
    def __str__(self):
Packit 6f3914
        return os.path.basename(self.pkg.location)
Packit 6f3914
Packit 6f3914
    def _target_params(self):
Packit 6f3914
        pkg = self.pkg
Packit 6f3914
        ctype, csum = pkg.returnIdSum()
Packit 6f3914
        ctype_code = libdnf.repo.PackageTarget.checksumType(ctype)
Packit 6f3914
        if ctype_code == libdnf.repo.PackageTarget.ChecksumType_UNKNOWN:
Packit 6f3914
            logger.warning(_("unsupported checksum type: %s"), ctype)
Packit 6f3914
Packit 6f3914
        return {
Packit 6f3914
            'relative_url': pkg.location,
Packit 6f3914
            'checksum_type': ctype_code,
Packit 6f3914
            'checksum': csum,
Packit 6f3914
            'expectedsize': pkg.downloadsize,
Packit 6f3914
            'base_url': pkg.baseurl,
Packit 6f3914
        }
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def download_size(self):
Packit 6f3914
        """Total size of the download."""
Packit 6f3914
        return self.pkg.downloadsize
Packit 6f3914
Packit 6f3914
Packit 6f3914
class RemoteRPMPayload(PackagePayload):
Packit 6f3914
Packit 6f3914
    def __init__(self, remote_location, conf, progress):
Packit 6f3914
        super(RemoteRPMPayload, self).__init__("unused_object", progress)
Packit 6f3914
        self.remote_location = remote_location
Packit 6f3914
        self.remote_size = 0
Packit 6f3914
        self.conf = conf
Packit 6f3914
        s = (self.conf.releasever or "") + self.conf.substitutions.get('basearch')
Packit 6f3914
        digest = hashlib.sha256(s.encode('utf8')).hexdigest()[:16]
Packit 6f3914
        repodir = "commandline-" + digest
Packit 6f3914
        self.pkgdir = os.path.join(self.conf.cachedir, repodir, "packages")
Packit 6f3914
        dnf.util.ensure_dir(self.pkgdir)
Packit 6f3914
        self.local_path = os.path.join(self.pkgdir, self.__str__().lstrip("/"))
Packit 6f3914
Packit 6f3914
    def __str__(self):
Packit 6f3914
        return os.path.basename(self.remote_location)
Packit 6f3914
Packit 6f3914
    def _progress_cb(self, cbdata, total, done):
Packit 6f3914
        self.remote_size = total
Packit 6f3914
        try:
Packit 6f3914
            self.progress.progress(self, done)
Packit 6f3914
        except Exception:
Packit 6f3914
            exc_type, exc_value, exc_traceback = sys.exc_info()
Packit 6f3914
            except_list = traceback.format_exception(exc_type, exc_value, exc_traceback)
Packit 6f3914
            logger.critical(''.join(except_list))
Packit 6f3914
Packit 6f3914
    def _librepo_target(self):
Packit 6f3914
        return libdnf.repo.PackageTarget(
Packit 6f3914
            self.conf._config, os.path.basename(self.remote_location),
Packit 6f3914
            self.pkgdir, 0, None, 0, os.path.dirname(self.remote_location),
Packit 6f3914
            True, 0, 0, self.callbacks)
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def download_size(self):
Packit 6f3914
        """Total size of the download."""
Packit 6f3914
        return self.remote_size
Packit 6f3914
Packit 6f3914
Packit 6f3914
class MDPayload(dnf.callback.Payload):
Packit 6f3914
Packit 6f3914
    def __init__(self, progress):
Packit 6f3914
        super(MDPayload, self).__init__(progress)
Packit 6f3914
        self._text = ""
Packit 6f3914
        self._download_size = 0
Packit 6f3914
        self.fastest_mirror_running = False
Packit 6f3914
        self.mirror_failures = set()
Packit 6f3914
Packit 6f3914
    def __str__(self):
Packit 6f3914
        if dnf.pycomp.PY3:
Packit 6f3914
            return self._text
Packit 6f3914
        else:
Packit 6f3914
            return self._text.encode('utf-8')
Packit 6f3914
Packit 6f3914
    def __unicode__(self):
Packit 6f3914
        return self._text
Packit 6f3914
Packit 6f3914
    def _progress_cb(self, cbdata, total, done):
Packit 6f3914
        self._download_size = total
Packit 6f3914
        self.progress.progress(self, done)
Packit 6f3914
Packit 6f3914
    def _fastestmirror_cb(self, cbdata, stage, data):
Packit 6f3914
        if stage == libdnf.repo.RepoCB.FastestMirrorStage_DETECTION:
Packit 6f3914
            # pinging mirrors, this might take a while
Packit 6f3914
            msg = _('determining the fastest mirror (%s hosts).. ') % data
Packit 6f3914
            self.fastest_mirror_running = True
Packit 6f3914
        elif stage == libdnf.repo.RepoCB.FastestMirrorStage_STATUS and self.fastest_mirror_running:
Packit 6f3914
            # done.. report but ignore any errors
Packit 6f3914
            msg = 'error: %s\n' % data if data else 'done.\n'
Packit 6f3914
        else:
Packit 6f3914
            return
Packit 6f3914
        self.progress.message(msg)
Packit 6f3914
Packit 6f3914
    def _mirror_failure_cb(self, cbdata, msg, url, metadata):
Packit 6f3914
        self.mirror_failures.add(msg)
Packit 6f3914
        msg = 'error: %s (%s).' % (msg, url)
Packit 6f3914
        logger.debug(msg)
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def download_size(self):
Packit 6f3914
        return self._download_size
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def progress(self):
Packit 6f3914
        return self._progress
Packit 6f3914
Packit 6f3914
    @progress.setter
Packit 6f3914
    def progress(self, progress):
Packit 6f3914
        if progress is None:
Packit 6f3914
            progress = dnf.callback.NullDownloadProgress()
Packit 6f3914
        self._progress = progress
Packit 6f3914
Packit 6f3914
    def start(self, text):
Packit 6f3914
        self._text = text
Packit 6f3914
        self.progress.start(1, 0)
Packit 6f3914
Packit 6f3914
    def end(self):
Packit 6f3914
        self._download_size = 0
Packit 6f3914
        self.progress.end(self, None, None)
Packit 6f3914
Packit 6f3914
Packit 6f3914
# use the local cache even if it's expired. download if there's no cache.
Packit 6f3914
SYNC_LAZY = libdnf.repo.Repo.SyncStrategy_LAZY
Packit 6f3914
# use the local cache, even if it's expired, never download.
Packit 6f3914
SYNC_ONLY_CACHE = libdnf.repo.Repo.SyncStrategy_ONLY_CACHE
Packit 6f3914
# try the cache, if it is expired download new md.
Packit 6f3914
SYNC_TRY_CACHE = libdnf.repo.Repo.SyncStrategy_TRY_CACHE
Packit 6f3914
Packit 6f3914
Packit 6f3914
class RepoCallbacks(libdnf.repo.RepoCB):
Packit 6f3914
    def __init__(self, repo):
Packit 6f3914
        super(RepoCallbacks, self).__init__()
Packit 6f3914
        self._repo = repo
Packit 6f3914
        self._md_pload = repo._md_pload
Packit 6f3914
Packit 6f3914
    def start(self, what):
Packit 6f3914
        self._md_pload.start(what)
Packit 6f3914
Packit 6f3914
    def end(self):
Packit 6f3914
        self._md_pload.end()
Packit 6f3914
Packit 6f3914
    def progress(self, totalToDownload, downloaded):
Packit 6f3914
        self._md_pload._progress_cb(None, totalToDownload, downloaded)
Packit 6f3914
        return 0
Packit 6f3914
Packit 6f3914
    def fastestMirror(self, stage, ptr):
Packit 6f3914
        self._md_pload._fastestmirror_cb(None, stage, ptr)
Packit 6f3914
Packit 6f3914
    def handleMirrorFailure(self, msg, url, metadata):
Packit 6f3914
        self._md_pload._mirror_failure_cb(None, msg, url, metadata)
Packit 6f3914
        return 0
Packit 6f3914
Packit 6f3914
    def repokeyImport(self, id, userid, fingerprint, url, timestamp):
Packit 6f3914
        return self._repo._key_import._confirm(id, userid, fingerprint, url, timestamp)
Packit 6f3914
Packit 6f3914
Packit 6f3914
class Repo(dnf.conf.RepoConf):
Packit 6f3914
    # :api
Packit 6f3914
    DEFAULT_SYNC = SYNC_TRY_CACHE
Packit 6f3914
Packit 6f3914
    def __init__(self, name=None, parent_conf=None):
Packit 6f3914
        # :api
Packit 6f3914
        super(Repo, self).__init__(section=name, parent=parent_conf)
Packit 6f3914
Packit 6f3914
        self._config.this.disown()  # _repo will be the owner of _config
Packit 6f3914
        self._repo = libdnf.repo.Repo(name if name else "", self._config)
Packit 6f3914
Packit 6f3914
        self._md_pload = MDPayload(dnf.callback.NullDownloadProgress())
Packit 6f3914
        self._callbacks = RepoCallbacks(self)
Packit 6f3914
        self._callbacks.this.disown()  # _repo will be the owner of callbacks
Packit 6f3914
        self._repo.setCallbacks(self._callbacks)
Packit 6f3914
Packit 6f3914
        self._pkgdir = None
Packit 6f3914
        self._key_import = _NullKeyImport()
Packit 6f3914
        self.metadata = None  # :api
Packit 6f3914
        self._repo.setSyncStrategy(self.DEFAULT_SYNC)
Packit 6f3914
        if parent_conf:
Packit 6f3914
            self._repo.setSubstitutions(parent_conf.substitutions)
Packit 6f3914
        self._substitutions = dnf.conf.substitutions.Substitutions()
Packit 6f3914
        self._check_config_file_age = parent_conf.check_config_file_age \
Packit 6f3914
            if parent_conf is not None else True
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def id(self):
Packit 6f3914
        # :api
Packit 6f3914
        return self._repo.getId()
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def repofile(self):
Packit 6f3914
        # :api
Packit 6f3914
        return self._repo.getRepoFilePath()
Packit 6f3914
Packit 6f3914
    @repofile.setter
Packit 6f3914
    def repofile(self, value):
Packit 6f3914
        self._repo.setRepoFilePath(value)
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def pkgdir(self):
Packit 6f3914
        # :api
Packit 6f3914
        if self._repo.isLocal():
Packit 6f3914
            return dnf.util.strip_prefix(self.baseurl[0], 'file://')
Packit 6f3914
        return self.cache_pkgdir()
Packit 6f3914
Packit 6f3914
    def cache_pkgdir(self):
Packit 6f3914
        if self._pkgdir is not None:
Packit 6f3914
            return self._pkgdir
Packit 6f3914
        return os.path.join(self._repo.getCachedir(), _PACKAGES_RELATIVE_DIR)
Packit 6f3914
Packit 6f3914
    @pkgdir.setter
Packit 6f3914
    def pkgdir(self, val):
Packit 6f3914
        # :api
Packit 6f3914
        self._pkgdir = val
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def _pubring_dir(self):
Packit 6f3914
        return os.path.join(self._repo.getCachedir(), 'pubring')
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def load_metadata_other(self):
Packit 6f3914
        return self._repo.getLoadMetadataOther()
Packit 6f3914
Packit 6f3914
    @load_metadata_other.setter
Packit 6f3914
    def load_metadata_other(self, val):
Packit 6f3914
        self._repo.setLoadMetadataOther(val)
Packit 6f3914
Packit 6f3914
    def __lt__(self, other):
Packit 6f3914
        return self.id < other.id
Packit 6f3914
Packit 6f3914
    def __repr__(self):
Packit 6f3914
        return "<%s %s>" % (self.__class__.__name__, self.id)
Packit 6f3914
Packit 6f3914
    def __setattr__(self, name, value):
Packit 6f3914
        super(Repo, self).__setattr__(name, value)
Packit 6f3914
Packit 6f3914
    def disable(self):
Packit 6f3914
        # :api
Packit 6f3914
        self._repo.disable()
Packit 6f3914
Packit 6f3914
    def enable(self):
Packit 6f3914
        # :api
Packit 6f3914
        self._repo.enable()
Packit 6f3914
Packit 6f3914
    def add_metadata_type_to_download(self, metadata_type):
Packit 6f3914
        # :api
Packit 6f3914
        """Ask for additional repository metadata type to download.
Packit 6f3914
Packit 6f3914
        Given metadata_type is appended to the default metadata set when
Packit 6f3914
        repository is downloaded.
Packit 6f3914
Packit 6f3914
        Parameters
Packit 6f3914
        ----------
Packit 6f3914
        metadata_type: string
Packit 6f3914
Packit 6f3914
        Example: add_metadata_type_to_download("productid")
Packit 6f3914
        """
Packit 6f3914
        self._repo.addMetadataTypeToDownload(metadata_type)
Packit 6f3914
Packit 6f3914
    def remove_metadata_type_from_download(self, metadata_type):
Packit 6f3914
        # :api
Packit 6f3914
        """Stop asking for this additional repository metadata type
Packit 6f3914
        in download.
Packit 6f3914
Packit 6f3914
        Given metadata_type is no longer downloaded by default
Packit 6f3914
        when this repository is downloaded.
Packit 6f3914
Packit 6f3914
        Parameters
Packit 6f3914
        ----------
Packit 6f3914
        metadata_type: string
Packit 6f3914
Packit 6f3914
        Example: remove_metadata_type_from_download("productid")
Packit 6f3914
        """
Packit 6f3914
        self._repo.removeMetadataTypeFromDownload(metadata_type)
Packit 6f3914
Packit 6f3914
    def get_metadata_path(self, metadata_type):
Packit 6f3914
        # :api
Packit 6f3914
        """Return path to the file with downloaded repository metadata of given type.
Packit 6f3914
Packit 6f3914
        Parameters
Packit 6f3914
        ----------
Packit 6f3914
        metadata_type: string
Packit 6f3914
        """
Packit 6f3914
        return self._repo.getMetadataPath(metadata_type)
Packit 6f3914
Packit 6f3914
    def get_metadata_content(self, metadata_type):
Packit 6f3914
        # :api
Packit 6f3914
        """Return content of the file with downloaded repository metadata of given type.
Packit 6f3914
Packit 6f3914
        Content of compressed metadata file is returned uncompressed.
Packit 6f3914
Packit 6f3914
        Parameters
Packit 6f3914
        ----------
Packit 6f3914
        metadata_type: string
Packit 6f3914
        """
Packit 6f3914
        return self._repo.getMetadataContent(metadata_type)
Packit 6f3914
Packit 6f3914
    def load(self):
Packit 6f3914
        # :api
Packit 6f3914
        """Load the metadata for this repo.
Packit 6f3914
Packit 6f3914
        Depending on the configuration and the age and consistence of data
Packit 6f3914
        available on the disk cache, either loads the metadata from the cache or
Packit 6f3914
        downloads them from the mirror, baseurl or metalink.
Packit 6f3914
Packit 6f3914
        This method will by default not try to refresh already loaded data if
Packit 6f3914
        called repeatedly.
Packit 6f3914
Packit 6f3914
        Returns True if this call to load() caused a fresh metadata download.
Packit 6f3914
Packit 6f3914
        """
Packit 6f3914
        ret = False
Packit 6f3914
        try:
Packit 6f3914
            ret = self._repo.load()
Packit 6f3914
        except RuntimeError as e:
Packit 6f3914
            if self._md_pload.mirror_failures:
Packit 6f3914
                msg = "Errors during downloading metadata for repository '%s':" % self.id
Packit 6f3914
                for failure in self._md_pload.mirror_failures:
Packit 6f3914
                    msg += "\n  - %s" % failure
Packit 6f3914
                logger.warning(msg)
Packit 6f3914
            raise dnf.exceptions.RepoError(str(e))
Packit 6f3914
        finally:
Packit 6f3914
            self._md_pload.mirror_failures = set()
Packit 6f3914
        self.metadata = Metadata(self._repo)
Packit 6f3914
        return ret
Packit 6f3914
Packit 6f3914
    def _metadata_expire_in(self):
Packit 6f3914
        """Get the number of seconds after which the cached metadata will expire.
Packit 6f3914
Packit 6f3914
        Returns a tuple, boolean whether there even is cached metadata and the
Packit 6f3914
        number of seconds it will expire in. Negative number means the metadata
Packit 6f3914
        has expired already, None that it never expires.
Packit 6f3914
Packit 6f3914
        """
Packit 6f3914
        if not self.metadata:
Packit 6f3914
            self._repo.loadCache(False)
Packit 6f3914
        if self.metadata:
Packit 6f3914
            if self.metadata_expire == -1:
Packit 6f3914
                return True, None
Packit 6f3914
            expiration = self._repo.getExpiresIn()
Packit 6f3914
            if self._repo.isExpired():
Packit 6f3914
                expiration = min(0, expiration)
Packit 6f3914
            return True, expiration
Packit 6f3914
        return False, 0
Packit 6f3914
Packit 6f3914
    def _set_key_import(self, key_import):
Packit 6f3914
        self._key_import = key_import
Packit 6f3914
Packit 6f3914
    def set_progress_bar(self, progress):
Packit 6f3914
        # :api
Packit 6f3914
        self._md_pload.progress = progress
Packit 6f3914
Packit 6f3914
    def get_http_headers(self):
Packit 6f3914
        # :api
Packit 6f3914
        """Returns user defined http headers.
Packit 6f3914
Packit 6f3914
        Returns
Packit 6f3914
        -------
Packit 6f3914
        headers : tuple of strings
Packit 6f3914
        """
Packit 6f3914
        return self._repo.getHttpHeaders()
Packit 6f3914
Packit 6f3914
    def set_http_headers(self, headers):
Packit 6f3914
        # :api
Packit 6f3914
        """Sets http headers.
Packit 6f3914
Packit 6f3914
        Sets new http headers and rewrites existing ones.
Packit 6f3914
Packit 6f3914
        Parameters
Packit 6f3914
        ----------
Packit 6f3914
        headers : tuple or list of strings
Packit 6f3914
            Example: set_http_headers(["User-Agent: Agent007", "MyFieldName: MyFieldValue"])
Packit 6f3914
        """
Packit 6f3914
        self._repo.setHttpHeaders(headers)
Packit 6f3914
Packit 6f3914
    def remote_location(self, location, schemes=('http', 'ftp', 'file', 'https')):
Packit 6f3914
        """
Packit 6f3914
        :param location: relative location inside the repo
Packit 6f3914
        :param schemes: list of allowed protocols. Default is ('http', 'ftp', 'file', 'https')
Packit 6f3914
        :return: absolute url (string) or None
Packit 6f3914
        """
Packit 6f3914
        def schemes_filter(url_list):
Packit 6f3914
            for url in url_list:
Packit 6f3914
                if schemes:
Packit 6f3914
                    s = dnf.pycomp.urlparse.urlparse(url)[0]
Packit 6f3914
                    if s in schemes:
Packit 6f3914
                        return os.path.join(url, location.lstrip('/'))
Packit 6f3914
                else:
Packit 6f3914
                    return os.path.join(url, location.lstrip('/'))
Packit 6f3914
            return None
Packit 6f3914
Packit 6f3914
        if not location:
Packit 6f3914
            return None
Packit 6f3914
Packit 6f3914
        mirrors = self._repo.getMirrors()
Packit 6f3914
        if mirrors:
Packit 6f3914
            return schemes_filter(mirrors)
Packit 6f3914
        elif self.baseurl:
Packit 6f3914
            return schemes_filter(self.baseurl)