Blame dnf/conf/config.py

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