Blame dnf/conf/config.py

Packit 6f3914
# dnf configuration classes.
Packit 6f3914
#
Packit 6f3914
# Copyright (C) 2016-2017 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.yum import misc
Packit 6f3914
from dnf.i18n import ucd, _
Packit 6f3914
from dnf.pycomp import basestring, urlparse
Packit 6f3914
Packit 6f3914
import fnmatch
Packit 6f3914
import dnf.conf.substitutions
Packit 6f3914
import dnf.const
Packit 6f3914
import dnf.exceptions
Packit 6f3914
import dnf.pycomp
Packit 6f3914
import dnf.util
Packit 6f3914
import hawkey
Packit 6f3914
import logging
Packit 6f3914
import os
Packit 6f3914
import libdnf.conf
Packit 6f3914
import libdnf.repo
Packit 6f3914
import tempfile
Packit 6f3914
Packit 6f3914
PRIO_EMPTY = libdnf.conf.Option.Priority_EMPTY
Packit 6f3914
PRIO_DEFAULT = libdnf.conf.Option.Priority_DEFAULT
Packit 6f3914
PRIO_MAINCONFIG = libdnf.conf.Option.Priority_MAINCONFIG
Packit 6f3914
PRIO_AUTOMATICCONFIG = libdnf.conf.Option.Priority_AUTOMATICCONFIG
Packit 6f3914
PRIO_REPOCONFIG = libdnf.conf.Option.Priority_REPOCONFIG
Packit 6f3914
PRIO_PLUGINDEFAULT = libdnf.conf.Option.Priority_PLUGINDEFAULT
Packit 6f3914
PRIO_PLUGINCONFIG = libdnf.conf.Option.Priority_PLUGINCONFIG
Packit 6f3914
PRIO_COMMANDLINE = libdnf.conf.Option.Priority_COMMANDLINE
Packit 6f3914
PRIO_RUNTIME = libdnf.conf.Option.Priority_RUNTIME
Packit 6f3914
Packit 6f3914
logger = logging.getLogger('dnf')
Packit 6f3914
Packit 6f3914
Packit 6f3914
class BaseConfig(object):
Packit 6f3914
    """Base class for storing configuration definitions.
Packit 6f3914
Packit 6f3914
       Subclass when creating your own definitions.
Packit 6f3914
Packit 6f3914
    """
Packit 6f3914
Packit 6f3914
    def __init__(self, config=None, section=None, parser=None):
Packit 6f3914
        self.__dict__["_config"] = config
Packit 6f3914
        self._section = section
Packit 6f3914
Packit 6f3914
    def __getattr__(self, name):
Packit 6f3914
        if "_config" not in self.__dict__:
Packit 6f3914
            raise AttributeError("'{}' object has no attribute '{}'".format(self.__class__, name))
Packit 6f3914
        option = getattr(self._config, name)
Packit 6f3914
        if option is None:
Packit 6f3914
            return None
Packit 6f3914
        try:
Packit 6f3914
            value = option().getValue()
Packit 6f3914
        except Exception as ex:
Packit 6f3914
            return None
Packit 6f3914
        if isinstance(value, str):
Packit 6f3914
            return ucd(value)
Packit 6f3914
        return value
Packit 6f3914
Packit 6f3914
    def __setattr__(self, name, value):
Packit 6f3914
        option = getattr(self._config, name, None)
Packit 6f3914
        if option is None:
Packit 6f3914
            # unknown config option, store to BaseConfig only
Packit 6f3914
            return super(BaseConfig, self).__setattr__(name, value)
Packit 6f3914
        self._set_value(name, value, PRIO_RUNTIME)
Packit 6f3914
Packit 6f3914
    def __str__(self):
Packit 6f3914
        out = []
Packit 6f3914
        out.append('[%s]' % self._section)
Packit 6f3914
        if self._config:
Packit 6f3914
            for optBind in self._config.optBinds():
Packit 6f3914
                try:
Packit 6f3914
                    value = optBind.second.getValueString()
Packit 6f3914
                except RuntimeError:
Packit 6f3914
                    value = ""
Packit 6f3914
                out.append('%s: %s' % (optBind.first, value))
Packit 6f3914
        return '\n'.join(out)
Packit 6f3914
Packit 6f3914
    def _has_option(self, name):
Packit 6f3914
        method = getattr(self._config, name, None)
Packit 6f3914
        return method is not None
Packit 6f3914
Packit 6f3914
    def _get_value(self, name):
Packit 6f3914
        method = getattr(self._config, name, None)
Packit 6f3914
        if method is None:
Packit 6f3914
            return None
Packit 6f3914
        return method().getValue()
Packit 6f3914
Packit 6f3914
    def _get_priority(self, name):
Packit 6f3914
        method = getattr(self._config, name, None)
Packit 6f3914
        if method is None:
Packit 6f3914
            return None
Packit 6f3914
        return method().getPriority()
Packit 6f3914
Packit 6f3914
    def _set_value(self, name, value, priority=PRIO_RUNTIME):
Packit 6f3914
        """Set option's value if priority is equal or higher
Packit 6f3914
           than current priority."""
Packit 6f3914
        method = getattr(self._config, name, None)
Packit 6f3914
        if method is None:
Packit 6f3914
            raise Exception("Option \"" + name + "\" does not exists")
Packit 6f3914
        option = method()
Packit 6f3914
        if value is None:
Packit 6f3914
            try:
Packit 6f3914
                option.set(priority, value)
Packit 6f3914
            except Exception:
Packit 6f3914
                pass
Packit 6f3914
        else:
Packit 6f3914
            try:
Packit 6f3914
                if isinstance(value, list) or isinstance(value, tuple):
Packit 6f3914
                    option.set(priority, libdnf.conf.VectorString(value))
Packit 6f3914
                elif (isinstance(option, libdnf.conf.OptionBool)
Packit 6f3914
                      or isinstance(option, libdnf.conf.OptionChildBool)
Packit 6f3914
                      ) and isinstance(value, int):
Packit 6f3914
                    option.set(priority, bool(value))
Packit 6f3914
                else:
Packit 6f3914
                    option.set(priority, value)
Packit 6f3914
            except RuntimeError as e:
Packit 6f3914
                raise dnf.exceptions.ConfigError(_("Error parsing '%s': %s")
Packit 6f3914
                                                 % (value, str(e)),
Packit 6f3914
                                                 raw_error=str(e))
Packit 6f3914
Packit 6f3914
    def _populate(self, parser, section, filename, priority=PRIO_DEFAULT):
Packit 6f3914
        """Set option values from an INI file section."""
Packit 6f3914
        if parser.hasSection(section):
Packit 6f3914
            for name in parser.options(section):
Packit 6f3914
                value = parser.getSubstitutedValue(section, name)
Packit 6f3914
                if not value or value == 'None':
Packit 6f3914
                    value = ''
Packit 6f3914
                if hasattr(self._config, name):
Packit 6f3914
                    try:
Packit 6f3914
                        self._config.optBinds().at(name).newString(priority, value)
Packit 6f3914
                    except RuntimeError as e:
Packit 6f3914
                        logger.debug(_('Unknown configuration value: %s=%s in %s; %s'),
Packit 6f3914
                                     ucd(name), ucd(value), ucd(filename), str(e))
Packit 6f3914
                else:
Packit 6f3914
                    if name == 'arch' and hasattr(self, name):
Packit 6f3914
                        setattr(self, name, value)
Packit 6f3914
                    else:
Packit 6f3914
                        logger.debug(
Packit 6f3914
                            _('Unknown configuration option: %s = %s in %s'),
Packit 6f3914
                            ucd(name), ucd(value), ucd(filename))
Packit 6f3914
Packit 6f3914
    def dump(self):
Packit 6f3914
        # :api
Packit 6f3914
        """Return a string representing the values of all the
Packit 6f3914
           configuration options.
Packit 6f3914
        """
Packit 6f3914
        output = ['[%s]' % self._section]
Packit 6f3914
Packit 6f3914
        if self._config:
Packit 6f3914
            for optBind in self._config.optBinds():
Packit 6f3914
                # if not opt._is_runtimeonly():
Packit 6f3914
                try:
Packit 6f3914
                    output.append('%s = %s' % (optBind.first, optBind.second.getValueString()))
Packit 6f3914
                except RuntimeError:
Packit 6f3914
                    pass
Packit 6f3914
Packit 6f3914
        return '\n'.join(output) + '\n'
Packit 6f3914
Packit 6f3914
    @staticmethod
Packit 6f3914
    def write_raw_configfile(filename, section_id, substitutions, modify):
Packit 6f3914
        # :api
Packit 6f3914
        """
Packit 6f3914
        filename   - name of config file (.conf or .repo)
Packit 6f3914
        section_id - id of modified section (e.g. main, fedora, updates)
Packit 6f3914
        substitutions - instance of base.conf.substitutions
Packit 6f3914
        modify     - dict of modified options
Packit 6f3914
        """
Packit 6f3914
        parser = libdnf.conf.ConfigParser()
Packit 6f3914
        parser.read(filename)
Packit 6f3914
Packit 6f3914
        # b/c repoids can have $values in them we need to map both ways to figure
Packit 6f3914
        # out which one is which
Packit 6f3914
        if not parser.hasSection(section_id):
Packit 6f3914
            for sect in parser.getData():
Packit 6f3914
                if libdnf.conf.ConfigParser.substitute(sect, substitutions) == section_id:
Packit 6f3914
                    section_id = sect
Packit 6f3914
Packit 6f3914
        for name, value in modify.items():
Packit 6f3914
            if isinstance(value, list):
Packit 6f3914
                value = ' '.join(value)
Packit 6f3914
            parser.setValue(section_id, name, value)
Packit 6f3914
Packit 6f3914
        parser.write(filename, False)
Packit 6f3914
Packit 6f3914
Packit 6f3914
class MainConf(BaseConfig):
Packit 6f3914
    # :api
Packit 6f3914
    """Configuration option definitions for dnf.conf's [main] section."""
Packit 6f3914
    def __init__(self, section='main', parser=None):
Packit 6f3914
        # pylint: disable=R0915
Packit 6f3914
        config = libdnf.conf.ConfigMain()
Packit 6f3914
        super(MainConf, self).__init__(config, section, parser)
Packit 6f3914
        self._set_value('pluginpath', [dnf.const.PLUGINPATH], PRIO_DEFAULT)
Packit 6f3914
        self._set_value('pluginconfpath', [dnf.const.PLUGINCONFPATH], PRIO_DEFAULT)
Packit 6f3914
        self.substitutions = dnf.conf.substitutions.Substitutions()
Packit 6f3914
        self.arch = hawkey.detect_arch()
Packit 6f3914
        self._config.system_cachedir().set(PRIO_DEFAULT, dnf.const.SYSTEM_CACHEDIR)
Packit 6f3914
Packit 6f3914
        # setup different cache and log for non-privileged users
Packit 6f3914
        if dnf.util.am_i_root():
Packit 6f3914
            cachedir = dnf.const.SYSTEM_CACHEDIR
Packit 6f3914
            logdir = '/var/log'
Packit 6f3914
        else:
Packit 6f3914
            try:
Packit 6f3914
                cachedir = logdir = misc.getCacheDir()
Packit 6f3914
            except (IOError, OSError) as e:
Packit 6f3914
                msg = _('Could not set cachedir: {}').format(ucd(e))
Packit 6f3914
                raise dnf.exceptions.Error(msg)
Packit 6f3914
Packit 6f3914
        self._config.cachedir().set(PRIO_DEFAULT, cachedir)
Packit 6f3914
        self._config.logdir().set(PRIO_DEFAULT, logdir)
Packit 6f3914
Packit 6f3914
        # track list of temporary files created
Packit 6f3914
        self.tempfiles = []
Packit 6f3914
Packit 6f3914
    def __del__(self):
Packit 6f3914
        for file_name in self.tempfiles:
Packit 6f3914
            os.unlink(file_name)
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def get_reposdir(self):
Packit 6f3914
        # :api
Packit 6f3914
        """Returns the value of reposdir"""
Packit 6f3914
        myrepodir = None
Packit 6f3914
        # put repo file into first reposdir which exists or create it
Packit 6f3914
        for rdir in self._get_value('reposdir'):
Packit 6f3914
            if os.path.exists(rdir):
Packit 6f3914
                myrepodir = rdir
Packit 6f3914
                break
Packit 6f3914
Packit 6f3914
        if not myrepodir:
Packit 6f3914
            myrepodir = self._get_value('reposdir')[0]
Packit 6f3914
            dnf.util.ensure_dir(myrepodir)
Packit 6f3914
        return myrepodir
Packit 6f3914
Packit 6f3914
    def _check_remote_file(self, optname):
Packit 6f3914
        """
Packit 6f3914
        In case the option value is a remote URL, download it to the temporary location
Packit 6f3914
        and use this temporary file instead.
Packit 6f3914
        """
Packit 6f3914
        prio = self._get_priority(optname)
Packit 6f3914
        val = self._get_value(optname)
Packit 6f3914
        if isinstance(val, basestring):
Packit 6f3914
            location = urlparse.urlparse(val)
Packit 6f3914
            if location[0] in ('file', ''):
Packit 6f3914
                # just strip the file:// prefix
Packit 6f3914
                self._set_value(optname, location.path, prio)
Packit 6f3914
            else:
Packit 6f3914
                downloader = libdnf.repo.Downloader()
Packit 6f3914
                temp_fd, temp_path = tempfile.mkstemp(prefix='dnf-downloaded-config-')
Packit 6f3914
                self.tempfiles.append(temp_path)
Packit 6f3914
                try:
Packit 6f3914
                    downloader.downloadURL(None, val, temp_fd)
Packit 6f3914
                except RuntimeError as e:
Packit 6f3914
                    raise dnf.exceptions.ConfigError(
Packit 6f3914
                        _('Configuration file URL "{}" could not be downloaded:\n'
Packit 6f3914
                          '  {}').format(val, str(e)))
Packit 6f3914
                else:
Packit 6f3914
                    self._set_value(optname, temp_path, prio)
Packit 6f3914
                finally:
Packit 6f3914
                    os.close(temp_fd)
Packit 6f3914
Packit 6f3914
    def _search_inside_installroot(self, optname):
Packit 6f3914
        """
Packit 6f3914
        Return root used as prefix for option (installroot or "/"). When specified from commandline
Packit 6f3914
        it returns value from conf.installroot
Packit 6f3914
        """
Packit 6f3914
        installroot = self._get_value('installroot')
Packit 6f3914
        if installroot == "/":
Packit 6f3914
            return installroot
Packit 6f3914
        prio = self._get_priority(optname)
Packit 6f3914
        # don't modify paths specified on commandline
Packit 6f3914
        if prio >= PRIO_COMMANDLINE:
Packit 6f3914
            return installroot
Packit 6f3914
        val = self._get_value(optname)
Packit 6f3914
        # if it exists inside installroot use it (i.e. adjust configuration)
Packit 6f3914
        # for lists any component counts
Packit 6f3914
        if not isinstance(val, str):
Packit 6f3914
            if any(os.path.exists(os.path.join(installroot, p.lstrip('/'))) for p in val):
Packit 6f3914
                self._set_value(
Packit 6f3914
                    optname,
Packit 6f3914
                    libdnf.conf.VectorString([self._prepend_installroot_path(p) for p in val]),
Packit 6f3914
                    prio
Packit 6f3914
                )
Packit 6f3914
                return installroot
Packit 6f3914
        elif os.path.exists(os.path.join(installroot, val.lstrip('/'))):
Packit 6f3914
            self._set_value(optname, self._prepend_installroot_path(val), prio)
Packit 6f3914
            return installroot
Packit 6f3914
        return "/"
Packit 6f3914
Packit 6f3914
    def prepend_installroot(self, optname):
Packit 6f3914
        # :api
Packit 6f3914
        prio = self._get_priority(optname)
Packit 6f3914
        new_path = self._prepend_installroot_path(self._get_value(optname))
Packit 6f3914
        self._set_value(optname, new_path, prio)
Packit 6f3914
Packit 6f3914
    def _prepend_installroot_path(self, path):
Packit 6f3914
        root_path = os.path.join(self._get_value('installroot'), path.lstrip('/'))
Packit 6f3914
        return libdnf.conf.ConfigParser.substitute(root_path, self.substitutions)
Packit 6f3914
Packit 6f3914
    def _configure_from_options(self, opts):
Packit 6f3914
        """Configure parts of CLI from the opts """
Packit 6f3914
        config_args = ['plugins', 'version', 'config_file_path',
Packit 6f3914
                       'debuglevel', 'errorlevel', 'installroot',
Packit 6f3914
                       'best', 'assumeyes', 'assumeno', 'clean_requirements_on_remove', 'gpgcheck',
Packit 6f3914
                       'showdupesfromrepos', 'plugins', 'ip_resolve',
Packit 6f3914
                       'rpmverbosity', 'disable_excludes', 'color',
Packit 6f3914
                       'downloadonly', 'exclude', 'excludepkgs', 'skip_broken',
Packit 6f3914
                       'tsflags', 'arch', 'basearch', 'ignorearch', 'cacheonly', 'comment']
Packit 6f3914
Packit 6f3914
        for name in config_args:
Packit 6f3914
            value = getattr(opts, name, None)
Packit 6f3914
            if value is not None and value != []:
Packit 6f3914
                if self._has_option(name):
Packit 6f3914
                    appendValue = False
Packit 6f3914
                    if self._config:
Packit 6f3914
                        try:
Packit 6f3914
                            appendValue = self._config.optBinds().at(name).getAddValue()
Packit 6f3914
                        except RuntimeError:
Packit 6f3914
                            # fails if option with "name" does not exist in _config (libdnf)
Packit 6f3914
                            pass
Packit 6f3914
                    if appendValue:
Packit 6f3914
                        add_priority = dnf.conf.PRIO_COMMANDLINE
Packit 6f3914
                        if add_priority < self._get_priority(name):
Packit 6f3914
                            add_priority = self._get_priority(name)
Packit 6f3914
                        for item in value:
Packit 6f3914
                            if item:
Packit 6f3914
                                self._set_value(name, self._get_value(name) + [item], add_priority)
Packit 6f3914
                            else:
Packit 6f3914
                                self._set_value(name, [], dnf.conf.PRIO_COMMANDLINE)
Packit 6f3914
                    else:
Packit 6f3914
                        self._set_value(name, value, dnf.conf.PRIO_COMMANDLINE)
Packit 6f3914
                elif hasattr(self, name):
Packit 6f3914
                    setattr(self, name, value)
Packit 6f3914
                else:
Packit 6f3914
                    logger.warning(_('Unknown configuration option: %s = %s'),
Packit 6f3914
                                   ucd(name), ucd(value))
Packit 6f3914
Packit 6f3914
        if getattr(opts, 'gpgcheck', None) is False:
Packit 6f3914
            self._set_value("localpkg_gpgcheck", False, dnf.conf.PRIO_COMMANDLINE)
Packit 6f3914
Packit 6f3914
        if hasattr(opts, 'main_setopts'):
Packit 6f3914
            # now set all the non-first-start opts from main from our setopts
Packit 6f3914
            # pylint: disable=W0212
Packit 6f3914
            for name, values in opts.main_setopts.items():
Packit 6f3914
                for val in values:
Packit 6f3914
                    if hasattr(self._config, name):
Packit 6f3914
                        try:
Packit 6f3914
                            # values in main_setopts are strings, try to parse it using newString()
Packit 6f3914
                            self._config.optBinds().at(name).newString(PRIO_COMMANDLINE, val)
Packit 6f3914
                        except RuntimeError as e:
Packit 6f3914
                            raise dnf.exceptions.ConfigError(
Packit 6f3914
                                _("Error parsing --setopt with key '%s', value '%s': %s")
Packit 6f3914
                                % (name, val, str(e)), raw_error=str(e))
Packit 6f3914
                    else:
Packit 6f3914
                        # if config option with "name" doesn't exist in _config, it could be defined
Packit 6f3914
                        # only in Python layer
Packit 6f3914
                        if hasattr(self, name):
Packit 6f3914
                            setattr(self, name, val)
Packit 6f3914
                        else:
Packit 6f3914
                            msg = _("Main config did not have a %s attr. before setopt")
Packit 6f3914
                            logger.warning(msg, name)
Packit 6f3914
Packit 6f3914
    def exclude_pkgs(self, pkgs):
Packit 6f3914
        # :api
Packit 6f3914
        name = "excludepkgs"
Packit 6f3914
Packit 6f3914
        if pkgs is not None and pkgs != []:
Packit 6f3914
            if self._has_option(name):
Packit 6f3914
                self._set_value(name, pkgs, dnf.conf.PRIO_COMMANDLINE)
Packit 6f3914
            else:
Packit 6f3914
                logger.warning(_('Unknown configuration option: %s = %s'),
Packit 6f3914
                               ucd(name), ucd(pkgs))
Packit 6f3914
Packit 6f3914
    def _adjust_conf_options(self):
Packit 6f3914
        """Adjust conf options interactions"""
Packit 6f3914
Packit 6f3914
        skip_broken_val = self._get_value('skip_broken')
Packit 6f3914
        if skip_broken_val:
Packit 6f3914
            self._set_value('strict', not skip_broken_val, self._get_priority('skip_broken'))
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def releasever(self):
Packit 6f3914
        # :api
Packit 6f3914
        return self.substitutions.get('releasever')
Packit 6f3914
Packit 6f3914
    @releasever.setter
Packit 6f3914
    def releasever(self, val):
Packit 6f3914
        # :api
Packit 6f3914
        if val is None:
Packit 6f3914
            self.substitutions.pop('releasever', None)
Packit 6f3914
            return
Packit 6f3914
        self.substitutions['releasever'] = str(val)
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def arch(self):
Packit 6f3914
        # :api
Packit 6f3914
        return self.substitutions.get('arch')
Packit 6f3914
Packit 6f3914
    @arch.setter
Packit 6f3914
    def arch(self, val):
Packit 6f3914
        # :api
Packit 6f3914
Packit 6f3914
        if val is None:
Packit 6f3914
            self.substitutions.pop('arch', None)
Packit 6f3914
            return
Packit 6f3914
        if val not in dnf.rpm._BASEARCH_MAP.keys():
Packit 6f3914
            msg = _('Incorrect or unknown "{}": {}')
Packit 6f3914
            raise dnf.exceptions.Error(msg.format("arch", val))
Packit 6f3914
        self.substitutions['arch'] = val
Packit 6f3914
        self.basearch = dnf.rpm.basearch(val)
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def basearch(self):
Packit 6f3914
        # :api
Packit 6f3914
        return self.substitutions.get('basearch')
Packit 6f3914
Packit 6f3914
    @basearch.setter
Packit 6f3914
    def basearch(self, val):
Packit 6f3914
        # :api
Packit 6f3914
Packit 6f3914
        if val is None:
Packit 6f3914
            self.substitutions.pop('basearch', None)
Packit 6f3914
            return
Packit 6f3914
        if val not in dnf.rpm._BASEARCH_MAP.values():
Packit 6f3914
            msg = _('Incorrect or unknown "{}": {}')
Packit 6f3914
            raise dnf.exceptions.Error(msg.format("basearch", val))
Packit 6f3914
        self.substitutions['basearch'] = val
Packit 6f3914
Packit 6f3914
    def read(self, filename=None, priority=PRIO_DEFAULT):
Packit 6f3914
        # :api
Packit 6f3914
        if filename is None:
Packit 6f3914
            filename = self._get_value('config_file_path')
Packit 6f3914
        parser = libdnf.conf.ConfigParser()
Packit 6f3914
        try:
Packit 6f3914
            parser.read(filename)
Packit 6f3914
        except RuntimeError as e:
Packit 6f3914
            raise dnf.exceptions.ConfigError(_('Parsing file "%s" failed: %s') % (filename, e))
Packit 6f3914
        except IOError as e:
Packit 6f3914
            logger.warning(e)
Packit 6f3914
        self._populate(parser, self._section, filename, priority)
Packit 6f3914
Packit 6f3914
        # update to where we read the file from
Packit 6f3914
        self._set_value('config_file_path', filename, priority)
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def verbose(self):
Packit 6f3914
        return self._get_value('debuglevel') >= dnf.const.VERBOSE_LEVEL
Packit 6f3914
Packit 6f3914
Packit 6f3914
class RepoConf(BaseConfig):
Packit 6f3914
    """Option definitions for repository INI file sections."""
Packit 6f3914
Packit 6f3914
    def __init__(self, parent, section=None, parser=None):
Packit 6f3914
        masterConfig = parent._config if parent else libdnf.conf.ConfigMain()
Packit 6f3914
        super(RepoConf, self).__init__(libdnf.conf.ConfigRepo(masterConfig), section, parser)
Packit 6f3914
        # Do not remove! Attribute is a reference holder.
Packit 6f3914
        # Prevents premature removal of the masterConfig. The libdnf ConfigRepo points to it.
Packit 6f3914
        self._masterConfigRefHolder = masterConfig
Packit 6f3914
        if section:
Packit 6f3914
            self._config.name().set(PRIO_DEFAULT, section)
Packit 6f3914
Packit 6f3914
    def _configure_from_options(self, opts):
Packit 6f3914
        """Configure repos from the opts. """
Packit 6f3914
Packit 6f3914
        if getattr(opts, 'gpgcheck', None) is False:
Packit 6f3914
            for optname in ['gpgcheck', 'repo_gpgcheck']:
Packit 6f3914
                self._set_value(optname, False, dnf.conf.PRIO_COMMANDLINE)
Packit 6f3914
Packit 6f3914
        repo_setopts = getattr(opts, 'repo_setopts', {})
Packit 6f3914
        for repoid, setopts in repo_setopts.items():
Packit 6f3914
            if not fnmatch.fnmatch(self._section, repoid):
Packit 6f3914
                continue
Packit 6f3914
            for name, values in setopts.items():
Packit 6f3914
                for val in values:
Packit 6f3914
                    if hasattr(self._config, name):
Packit 6f3914
                        try:
Packit 6f3914
                            # values in repo_setopts are strings, try to parse it using newString()
Packit 6f3914
                            self._config.optBinds().at(name).newString(PRIO_COMMANDLINE, val)
Packit 6f3914
                        except RuntimeError as e:
Packit 6f3914
                            raise dnf.exceptions.ConfigError(
Packit 6f3914
                                _("Error parsing --setopt with key '%s.%s', value '%s': %s")
Packit 6f3914
                                % (self._section, name, val, str(e)), raw_error=str(e))
Packit 6f3914
                    else:
Packit 6f3914
                        msg = _("Repo %s did not have a %s attr. before setopt")
Packit 6f3914
                        logger.warning(msg, self._section, name)