Blame dnf/repo.py

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