Blame dnf/repodict.py

Packit 6f3914
# repodict.py
Packit 6f3914
# Managing repo configuration in DNF.
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 unicode_literals
Packit 6f3914
from dnf.exceptions import ConfigError
Packit 6f3914
from dnf.i18n import _
Packit 6f3914
Packit 6f3914
import dnf.util
Packit 6f3914
import libdnf.conf
Packit 6f3914
import fnmatch
Packit 6f3914
import os
Packit 6f3914
Packit 6f3914
logger = dnf.util.logger
Packit 6f3914
Packit 6f3914
Packit 6f3914
class RepoDict(dict):
Packit 6f3914
    # :api
Packit 6f3914
    def add(self, repo):
Packit 6f3914
        # :api
Packit 6f3914
        id_ = repo.id
Packit 6f3914
        if id_ in self:
Packit 6f3914
            msg = 'Repository %s is listed more than once in the configuration'
Packit 6f3914
            raise ConfigError(msg % id_)
Packit 6f3914
        try:
Packit 6f3914
            repo._repo.verify()
Packit 6f3914
        except RuntimeError as e:
Packit 6f3914
            raise ConfigError("{0}".format(e))
Packit 6f3914
        self[id_] = repo
Packit 6f3914
Packit 6f3914
    def all(self):
Packit 6f3914
        # :api
Packit 6f3914
        return dnf.util.MultiCallList(self.values())
Packit 6f3914
Packit 6f3914
    def _any_enabled(self):
Packit 6f3914
        return not dnf.util.empty(self.iter_enabled())
Packit 6f3914
Packit 6f3914
    def _enable_sub_repos(self, sub_name_fn):
Packit 6f3914
        for repo in self.iter_enabled():
Packit 6f3914
            for found in self.get_matching(sub_name_fn(repo.id)):
Packit 6f3914
                if not found.enabled:
Packit 6f3914
                    logger.info(_('enabling %s repository'), found.id)
Packit 6f3914
                    found.enable()
Packit 6f3914
Packit 6f3914
    def add_new_repo(self, repoid, conf, baseurl=(), **kwargs):
Packit 6f3914
        # :api
Packit 6f3914
        """
Packit 6f3914
        Creates new repo object and add it into RepoDict. Variables in provided values will be
Packit 6f3914
        automatically substituted using conf.substitutions (like $releasever, ...)
Packit 6f3914
Packit 6f3914
        @param repoid: Repo ID - string
Packit 6f3914
        @param conf: dnf Base().conf object
Packit 6f3914
        @param baseurl: List of strings
Packit 6f3914
        @param kwargs: keys and values that will be used to setattr on dnf.repo.Repo() object
Packit 6f3914
        @return: dnf.repo.Repo() object
Packit 6f3914
        """
Packit 6f3914
        def substitute(values):
Packit 6f3914
            if isinstance(values, str):
Packit 6f3914
                return libdnf.conf.ConfigParser.substitute(values, conf.substitutions)
Packit 6f3914
            elif isinstance(values, list) or isinstance(values, tuple):
Packit 6f3914
                substituted = []
Packit 6f3914
                for value in values:
Packit 6f3914
                    if isinstance(value, str):
Packit 6f3914
                        substituted.append(
Packit 6f3914
                            libdnf.conf.ConfigParser.substitute(value, conf.substitutions))
Packit 6f3914
                    if substituted:
Packit 6f3914
                        return substituted
Packit 6f3914
            return values
Packit 6f3914
Packit 6f3914
        repo = dnf.repo.Repo(repoid, conf)
Packit 6f3914
        for path in baseurl:
Packit 6f3914
            if '://' not in path:
Packit 6f3914
                path = 'file://{}'.format(os.path.abspath(path))
Packit 6f3914
            repo.baseurl += [substitute(path)]
Packit 6f3914
        for (key, value) in kwargs.items():
Packit 6f3914
            setattr(repo, key, substitute(value))
Packit 6f3914
        self.add(repo)
Packit 6f3914
        logger.info(_("Added %s repo from %s"), repoid, ', '.join(baseurl))
Packit 6f3914
        return repo
Packit 6f3914
Packit 6f3914
    def enable_debug_repos(self):
Packit 6f3914
        # :api
Packit 6f3914
        """enable debug repos corresponding to already enabled binary repos"""
Packit 6f3914
Packit 6f3914
        def debug_name(name):
Packit 6f3914
            return ("{}-debug-rpms".format(name[:-5]) if name.endswith("-rpms")
Packit 6f3914
                    else "{}-debuginfo".format(name))
Packit 6f3914
Packit 6f3914
        self._enable_sub_repos(debug_name)
Packit 6f3914
Packit 6f3914
    def enable_source_repos(self):
Packit 6f3914
        # :api
Packit 6f3914
        """enable source repos corresponding to already enabled binary repos"""
Packit 6f3914
Packit 6f3914
        def source_name(name):
Packit 6f3914
            return ("{}-source-rpms".format(name[:-5]) if name.endswith("-rpms")
Packit 6f3914
                    else "{}-source".format(name))
Packit 6f3914
Packit 6f3914
        self._enable_sub_repos(source_name)
Packit 6f3914
Packit 6f3914
    def get_matching(self, key):
Packit 6f3914
        # :api
Packit 6f3914
        if dnf.util.is_glob_pattern(key):
Packit 6f3914
            l = [self[k] for k in self if fnmatch.fnmatch(k, key)]
Packit 6f3914
            return dnf.util.MultiCallList(l)
Packit 6f3914
        repo = self.get(key, None)
Packit 6f3914
        if repo is None:
Packit 6f3914
            return dnf.util.MultiCallList([])
Packit 6f3914
        return dnf.util.MultiCallList([repo])
Packit 6f3914
Packit 6f3914
    def iter_enabled(self):
Packit 6f3914
        # :api
Packit 6f3914
        return (r for r in self.values() if r.enabled)
Packit 6f3914
Packit 6f3914
    def items(self):
Packit 6f3914
        """return repos sorted by priority"""
Packit 6f3914
        return (item for item in sorted(super(RepoDict, self).items(),
Packit 6f3914
                                        key=lambda x: (x[1].priority, x[1].cost)))
Packit 6f3914
Packit 6f3914
    def __iter__(self):
Packit 6f3914
        return self.keys()
Packit 6f3914
Packit 6f3914
    def keys(self):
Packit 6f3914
        return (k for k, v in self.items())
Packit 6f3914
Packit 6f3914
    def values(self):
Packit 6f3914
        return (v for k, v in self.items())