예제 #1
0
def readStartupConfig(configfile, root):
    '''
    Parse Yum's main configuration file and return a StartupConf instance.
    
    This is required in order to access configuration settings required as Yum
    starts up.

    @param configfile: The path to yum.conf.
    @param root: The base path to use for installation (typically '/')
    @return: A StartupConf instance.

    May raise Errors.ConfigError if a problem is detected with while parsing.
    '''

    # ' xemacs syntax hack

    StartupConf.installroot.default = root
    startupconf = StartupConf()
    startupconf.config_file_path = configfile
    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise Errors.ConfigError("Parsing file failed: %s" % e)
예제 #2
0
파일: config.py 프로젝트: lmacken/dnf
def readStartupConfig(configfile, root):
    """Parse Yum's main configuration file and return a
    :class:`StartupConf` instance.  This is required in order to
    access configuration settings required as Yum starts up.

    :param configfile: the path to yum.conf
    :param root: the base path to use for installation (typically '/')
    :return: A :class:`StartupConf` instance

    :raises: :class:`dnf.exceptions.ConfigError` if a problem is detected with while parsing.
    """

    StartupConf.installroot.default = root
    startupconf = StartupConf()
    startupconf.config_file_path = configfile
    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError as e:
        raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
    startupconf.populate(parser, 'main')

    # Check that plugin paths are all absolute
    for path in startupconf.pluginpath:
        if not path[0] == '/':
            raise dnf.exceptions.ConfigError("All plugin search paths must be absolute")
    # Stuff this here to avoid later re-parsing
    startupconf._parser = parser
    return startupconf
예제 #3
0
def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise Errors.ConfigError("Parsing file failed: %s" % e)
예제 #4
0
파일: config.py 프로젝트: harshithanaik/yum
def readStartupConfig(configfile, root, releasever=None):
    """Parse Yum's main configuration file and return a
    :class:`StartupConf` instance.  This is required in order to
    access configuration settings required as Yum starts up.

    :param configfile: the path to yum.conf
    :param root: the base path to use for installation (typically '/')
    :return: A :class:`StartupConf` instance

    :raises: :class:`Errors.ConfigError` if a problem is detected with while parsing.
    """

    # ' xemacs syntax hack

    StartupConf.installroot.default = root
    startupconf = StartupConf()
    startupconf.config_file_path = configfile
    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)

    yumvars = _getEnvVar()
    _read_yumvars(yumvars, startupconf.installroot)
    confpp_obj._vars = yumvars
    startupconf.yumvars = yumvars

    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise Errors.ConfigError("Parsing file failed: %s" % e)
예제 #5
0
def readStartupConfig(configfile, root, releasever=None):
    """Parse Yum's main configuration file and return a
    :class:`StartupConf` instance.  This is required in order to
    access configuration settings required as Yum starts up.

    :param configfile: the path to yum.conf
    :param root: the base path to use for installation (typically '/')
    :return: A :class:`StartupConf` instance

    :raises: :class:`Errors.ConfigError` if a problem is detected with while parsing.
    """

    # ' xemacs syntax hack

    StartupConf.installroot.default = root
    startupconf = StartupConf()
    startupconf.config_file_path = configfile
    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)

    yumvars = _getEnvVar()
    confpp_obj._vars = yumvars
    startupconf.yumvars = yumvars

    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise Errors.ConfigError("Parsing file failed: %s" % e)
예제 #6
0
def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise Errors.ConfigError("Parsing file failed: %s" % e)
예제 #7
0
def readStartupConfig(configfile, root):
    '''
    Parse Yum's main configuration file and return a StartupConf instance.
    
    This is required in order to access configuration settings required as Yum
    starts up.

    @param configfile: The path to yum.conf.
    @param root: The base path to use for installation (typically '/')
    @return: A StartupConf instance.

    May raise Errors.ConfigError if a problem is detected with while parsing.
    '''

    # ' xemacs syntax hack

    StartupConf.installroot.default = root
    startupconf = StartupConf()
    startupconf.config_file_path = configfile
    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise Errors.ConfigError("Parsing file failed: %s" % e)
예제 #8
0
파일: config.py 프로젝트: harshithanaik/yum
def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
    """Parse the configuration file for version groups.
    
    :param configfile: the configuration file to read
    :return: a dictionary containing the parsed options
    """

    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise Errors.ConfigError("Parsing file failed: %s" % e)
예제 #9
0
def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
    """Parse the configuration file for version groups.
    
    :param configfile: the configuration file to read
    :return: a dictionary containing the parsed options
    """

    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise Errors.ConfigError("Parsing file failed: %s" % e)
예제 #10
0
파일: config.py 프로젝트: DNIWE-Systems/dnf
    def read(self, filename=None):
        # :api
        if filename is None:
            filename = self.config_file_path
        parser = ConfigParser()
        config_pp = ConfigPreProcessor(filename)
        try:
            parser.readfp(config_pp)
        except ParsingError as e:
            raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
        self.populate(parser, 'main')

        # update to where we read the file from
        self.config_file_path = filename
예제 #11
0
파일: config.py 프로젝트: hutarova/dnf
    def read(self, filename=None):
        # :api
        if filename is None:
            filename = self.config_file_path
        parser = ConfigParser()
        config_pp = ConfigPreProcessor(filename)
        try:
            parser.readfp(config_pp)
        except ParsingError as e:
            raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
        self.populate(parser, 'main')

        # update to where we read the file from
        self.config_file_path = filename
예제 #12
0
파일: config.py 프로젝트: lmacken/dnf
def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
    """Parse the configuration file for version groups.

    :param configfile: the configuration file to read
    :return: a dictionary containing the parsed options
    """

    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError as e:
        raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
    ret = {}
    for section in parser.sections():
        ret[section] = VersionGroupConf()
        ret[section].populate(parser, section)
    return ret
예제 #13
0
파일: config.py 프로젝트: hutarova/dnf
def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
    """Parse the configuration file for version groups.

    :param configfile: the configuration file to read
    :return: a dictionary containing the parsed options
    """

    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError as e:
        raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
    ret = {}
    for section in parser.sections():
        ret[section] = VersionGroupConf()
        ret[section].populate(parser, section)
    return ret
예제 #14
0
파일: config.py 프로젝트: ryanuber/dnf
def readStartupConfig(configfile, root):
    """Parse Yum's main configuration file and return a
    :class:`StartupConf` instance.  This is required in order to
    access configuration settings required as Yum starts up.

    :param configfile: the path to yum.conf
    :param root: the base path to use for installation (typically '/')
    :return: A :class:`StartupConf` instance

    :raises: :class:`dnf.exceptions.ConfigError` if a problem is detected with while parsing.
    """

    StartupConf.installroot.default = root
    startupconf = StartupConf()
    startupconf.config_file_path = configfile
    parser = ConfigParser()
    confpp_obj = ConfigPreProcessor(configfile)
    try:
        parser.readfp(confpp_obj)
    except ParsingError, e:
        raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
예제 #15
0
파일: config.py 프로젝트: edynox/dnf
    def read(self, filename=None, priority=PRIO_DEFAULT):
        # :api
        if filename is None:
            filename = self._get_value('config_file_path')
        self._parser = ConfigParser()
        config_pp = dnf.conf.parser.ConfigPreProcessor(filename)
        try:
            self._parser.readfp(config_pp)
        except ParsingError as e:
            raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
        self._populate(self._parser, self._section, filename, priority)

        # update to where we read the file from
        self._set_value('config_file_path', filename, priority)
예제 #16
0
    def read(self, filename=None, priority=PRIO_DEFAULT):
        # :api
        if filename is None:
            filename = self._get_value('config_file_path')
        self._parser = ConfigParser()
        config_pp = dnf.conf.parser.ConfigPreProcessor(filename)
        try:
            self._parser.readfp(config_pp)
        except ParsingError as e:
            raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
        self._populate(self._parser, self._section, filename, priority)

        # update to where we read the file from
        self._set_value('config_file_path', filename, priority)
예제 #17
0
class MainConf(BaseConfig):
    # :api
    """Configuration option definitions for dnf.conf's [main] section."""
    def __init__(self, section='main', parser=None):
        # pylint: disable=R0915
        super(MainConf, self).__init__(section, parser)
        self.substitutions = dnf.conf.substitutions.Substitutions()
        # setup different cache and log for non-priviledged users
        if dnf.util.am_i_root():
            cachedir = dnf.const.SYSTEM_CACHEDIR
            logdir = '/var/log'
        else:
            try:
                cachedir = logdir = misc.getCacheDir()
            except (IOError, OSError) as e:
                logger.critical(_('Could not set cachedir: %s'), ucd(e))

        self._add_option('debuglevel', IntOption(2, range_min=0,
                                                 range_max=10))  # :api
        self._add_option('errorlevel', IntOption(2, range_min=0, range_max=10))

        self._add_option('installroot', PathOption('/', abspath=True))  # :api
        self._add_option('config_file_path',
                         PathOption(dnf.const.CONF_FILENAME))  # :api
        self._add_option('plugins', BoolOption(True))
        self._add_option('pluginpath',
                         ListOption([dnf.const.PLUGINPATH]))  # :api
        self._add_option('pluginconfpath',
                         ListOption([dnf.const.PLUGINCONFPATH]))  # :api
        self._add_option('persistdir',
                         PathOption(dnf.const.PERSISTDIR))  # :api
        self._add_option('recent', IntOption(7, range_min=0))
        self._add_option('retries', PositiveIntOption(10, names_of_0=["0"]))
        self._add_option('reset_nice', BoolOption(True))

        self._add_option('cachedir', PathOption(cachedir))  # :api
        self._add_option('system_cachedir',
                         PathOption(dnf.const.SYSTEM_CACHEDIR))  # :api

        self._add_option('keepcache', BoolOption(False))
        self._add_option('logdir', Option(logdir))  # :api
        self._add_option('reposdir',
                         ListOption([
                             '/etc/yum.repos.d', '/etc/yum/repos.d',
                             '/etc/distro.repos.d'
                         ]))  # :api

        self._add_option('debug_solver', BoolOption(False))

        self._add_option('excludepkgs', ListAppendOption())
        self._add_option('includepkgs', ListAppendOption())
        self._add_option('exclude', self._get_option('excludepkgs'))
        # ^ compatibility with yum
        self._add_option('fastestmirror', BoolOption(False))
        self._add_option('proxy',
                         UrlOption(schemes=('http', 'ftp', 'https', 'socks5',
                                            'socks5h', 'socks4', 'socks4a'),
                                   allow_none=True))  # :api
        self._add_option('proxy_username', Option())  # :api
        self._add_option('proxy_password', Option())  # :api
        self._add_option('protected_packages',
                         ListOption("dnf glob:/etc/yum/protected.d/*.conf " \
                                    "glob:/etc/dnf/protected.d/*.conf")) #:api
        self._add_option('username', Option())  # :api
        self._add_option('password', Option())  # :api
        self._add_option('installonlypkgs',
                         ListAppendOption(dnf.const.INSTALLONLYPKGS))
        self._add_option('group_package_types',
                         ListOption(dnf.const.GROUP_PACKAGE_TYPES))
        # NOTE: If you set this to 2, then because it keeps the current
        # kernel it means if you ever install an "old" kernel it'll get rid
        # of the newest one so you probably want to use 3 as a minimum
        # ... if you turn it on.
        self._add_option('installonly_limit',
                         PositiveIntOption(0,
                                           range_min=2,
                                           names_of_0=["0", "<off>"]))  # :api
        self._add_option('tsflags', ListAppendOption())  # :api

        self._add_option('assumeyes', BoolOption(False))  # :api
        self._add_option('assumeno', BoolOption(False))
        self._add_option('check_config_file_age', BoolOption(True))
        self._add_option('defaultyes', BoolOption(False))
        self._add_option('diskspacecheck', BoolOption(True))
        self._add_option('gpgcheck', BoolOption(False))
        self._add_option('repo_gpgcheck', BoolOption(False))
        self._add_option('localpkg_gpgcheck', BoolOption(False))
        self._add_option('obsoletes', BoolOption(True))
        self._add_option('showdupesfromrepos', BoolOption(False))
        self._add_option('enabled', BoolOption(True))
        self._add_option('enablegroups', BoolOption(True))
        self._add_option('exit_on_lock', BoolOption(False))

        self._add_option('bandwidth', BytesOption(0))
        self._add_option('minrate', BytesOption(1000))
        self._add_option(
            'ip_resolve',
            CaselessSelectionOption(choices=('ipv4', 'ipv6', 'whatever'),
                                    mapper={
                                        '4': 'ipv4',
                                        '6': 'ipv6'
                                    }))
        self._add_option('throttle', ThrottleOption(0))
        self._add_option('timeout', SecondsOption(30))
        self._add_option('max_parallel_downloads', IntOption(None,
                                                             range_min=1))

        self._add_option('metadata_expire',
                         SecondsOption(60 * 60 * 48))  # 48 hours
        self._add_option('metadata_timer_sync',
                         SecondsOption(60 * 60 * 3))  #  3 hours
        self._add_option('disable_excludes', ListOption())
        self._add_option('multilib_policy',
                         SelectionOption('best',
                                         choices=('best', 'all')))  # :api
        self._add_option('best', BoolOption(False))  # :api
        self._add_option('install_weak_deps', BoolOption(True))
        self._add_option('bugtracker_url', Option(dnf.const.BUGTRACKER))

        self._add_option(
            'color',
            SelectionOption('auto',
                            choices=('auto', 'never', 'always'),
                            mapper={
                                'on': 'always',
                                'yes': 'always',
                                '1': 'always',
                                'true': 'always',
                                'off': 'never',
                                'no': 'never',
                                '0': 'never',
                                'false': 'never',
                                'tty': 'auto',
                                'if-tty': 'auto'
                            }))
        self._add_option('color_list_installed_older', Option('bold'))
        self._add_option('color_list_installed_newer', Option('bold,yellow'))
        self._add_option('color_list_installed_reinstall', Option('normal'))
        self._add_option('color_list_installed_extra', Option('bold,red'))
        self._add_option('color_list_available_upgrade', Option('bold,blue'))
        self._add_option('color_list_available_downgrade', Option('dim,cyan'))
        self._add_option('color_list_available_reinstall',
                         Option('bold,underline,green'))
        self._add_option('color_list_available_install', Option('normal'))
        self._add_option('color_update_installed', Option('normal'))
        self._add_option('color_update_local', Option('bold'))
        self._add_option('color_update_remote', Option('normal'))
        self._add_option('color_search_match', Option('bold'))

        self._add_option('sslcacert', PathOption())  # :api
        self._add_option('sslverify', BoolOption(True))  # :api
        self._add_option('sslclientcert', Option())  # :api
        self._add_option('sslclientkey', Option())  # :api
        self._add_option('deltarpm', BoolOption(True))
        self._add_option('deltarpm_percentage',
                         PositiveIntOption(75, names_of_0=["0", "<off>"]))

        self._add_option('history_record', BoolOption(True))
        self._add_option('history_record_packages', ListOption(['dnf', 'rpm']))

        self._add_option('rpmverbosity', Option('info'))
        self._add_option('strict', BoolOption(True))  # :api
        self._add_option('skip_broken',
                         BoolOption(False))  # :yum-compatibility
        self._add_option('autocheck_running_kernel',
                         BoolOption(True))  # :yum-compatibility
        self._add_option('clean_requirements_on_remove', BoolOption(True))
        self._add_option(
            'history_list_view',
            SelectionOption('commands',
                            choices=('single-user-commands', 'users',
                                     'commands'),
                            mapper={
                                'cmds': 'commands',
                                'default': 'commands'
                            }))
        self._add_option('upgrade_group_objects_upgrade',
                         BoolOption(True))  # :api

        # runtime only options
        self._add_option('downloadonly', BoolOption(False, runtimeonly=True))

    @property
    def get_reposdir(self):
        # :api
        """Returns the value of reposdir"""
        myrepodir = None
        # put repo file into first reposdir which exists or create it
        for rdir in self._get_value('reposdir'):
            if os.path.exists(rdir):
                myrepodir = rdir
                break

        if not myrepodir:
            myrepodir = self._get_value('reposdir')[0]
            dnf.util.ensure_dir(myrepodir)
        return myrepodir

    def _search_inside_installroot(self, optname):
        opt = self._get_option(optname)
        prio = opt._get_priority()
        # dont modify paths specified on commandline
        if prio >= PRIO_COMMANDLINE:
            return
        val = opt._get()
        # if it exists inside installroot use it (i.e. adjust configuration)
        # for lists any component counts
        if isinstance(val, list):
            if any(
                    os.path.exists(
                        os.path.join(self._get_value('installroot'),
                                     p.lstrip('/'))) for p in val):
                opt._set(
                    Value([self._prepend_installroot_path(p) for p in val],
                          prio))
        elif os.path.exists(
                os.path.join(self._get_value('installroot'), val.lstrip('/'))):
            self.prepend_installroot(optname)
            opt._set(Value(self._prepend_installroot_path(val), prio))

    def prepend_installroot(self, optname):
        # :api
        opt = self._get_option(optname)
        prio = opt._get_priority()
        new_path = self._prepend_installroot_path(opt._get())
        opt._set(Value(new_path, prio))

    def _prepend_installroot_path(self, path):
        root_path = os.path.join(self._get_value('installroot'),
                                 path.lstrip('/'))
        return dnf.conf.parser.substitute(root_path, self.substitutions)

    def _configure_from_options(self, opts):
        """Configure parts of CLI from the opts """

        config_args = [
            'plugins', 'version', 'config_file_path', 'debuglevel',
            'errorlevel', 'installroot', 'best', 'assumeyes', 'assumeno',
            'gpgcheck', 'showdupesfromrepos', 'plugins', 'ip_resolve',
            'rpmverbosity', 'disable_excludes', 'color', 'downloadonly',
            'exclude', 'excludepkgs', "skip_broken", 'tsflags'
        ]

        for name in config_args:
            value = getattr(opts, name, None)
            if value is not None and value != []:
                confopt = self._get_option(name)
                if confopt:
                    confopt._set(value, dnf.conf.PRIO_COMMANDLINE)
                else:
                    logger.warning(_('Unknown configuration option: %s = %s'),
                                   ucd(name), ucd(value))

        if hasattr(opts, 'main_setopts'):
            # now set all the non-first-start opts from main from our setopts
            # pylint: disable=W0212
            for name, val in opts.main_setopts._get_kwargs():
                opt = self._get_option(name)
                if opt:
                    opt._set(val, dnf.conf.PRIO_COMMANDLINE)
                else:
                    msg = "Main config did not have a %s attr. before setopt"
                    logger.warning(msg, name)

    def exclude_pkgs(self, pkgs):
        # :api
        name = "excludepkgs"

        if pkgs is not None and pkgs != []:
            confopt = self._get_option(name)
            if confopt:
                confopt._set(pkgs, dnf.conf.PRIO_COMMANDLINE)
            else:
                logger.warning(_('Unknown configuration option: %s = %s'),
                               ucd(name), ucd(pkgs))

    def _adjust_conf_options(self):
        """Adjust conf options interactions"""

        skip_broken = self._get_option('skip_broken')
        skip_broken_val = skip_broken._get()
        if skip_broken_val:
            strict = self._get_option('strict')
            strict._set(not skip_broken_val, skip_broken._get_priority())

    @property
    def releasever(self):
        # :api
        return self.substitutions.get('releasever')

    @releasever.setter
    def releasever(self, val):
        # :api
        if val is None:
            self.substitutions.pop('releasever', None)
            return
        self.substitutions['releasever'] = val

    def read(self, filename=None, priority=PRIO_DEFAULT):
        # :api
        if filename is None:
            filename = self._get_value('config_file_path')
        self._parser = ConfigParser()
        config_pp = dnf.conf.parser.ConfigPreProcessor(filename)
        try:
            self._parser.readfp(config_pp)
        except ParsingError as e:
            raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
        self._populate(self._parser, self._section, filename, priority)

        # update to where we read the file from
        self._set_value('config_file_path', filename, priority)

    @property
    def verbose(self):
        return self._get_value('debuglevel') >= dnf.const.VERBOSE_LEVEL
예제 #18
0
파일: config.py 프로젝트: edynox/dnf
class MainConf(BaseConfig):
    # :api
    """Configuration option definitions for dnf.conf's [main] section."""

    def __init__(self, section='main', parser=None):
        # pylint: disable=R0915
        super(MainConf, self).__init__(section, parser)
        self.substitutions = dnf.conf.substitutions.Substitutions()
        self.arch = hawkey.detect_arch()

        # setup different cache and log for non-priviledged users
        if dnf.util.am_i_root():
            cachedir = dnf.const.SYSTEM_CACHEDIR
            logdir = '/var/log'
        else:
            try:
                cachedir = logdir = misc.getCacheDir()
            except (IOError, OSError) as e:
                logger.critical(_('Could not set cachedir: %s'), ucd(e))

        self._add_option('debuglevel',
                         IntOption(2, range_min=0, range_max=10)) # :api
        self._add_option('errorlevel', IntOption(2, range_min=0, range_max=10))

        self._add_option('installroot', PathOption('/', abspath=True)) # :api
        self._add_option('config_file_path',
                         PathOption(dnf.const.CONF_FILENAME)) # :api
        self._add_option('plugins', BoolOption(True))
        self._add_option('pluginpath', ListOption([dnf.const.PLUGINPATH])) # :api
        self._add_option('pluginconfpath',
                         ListOption([dnf.const.PLUGINCONFPATH])) # :api
        self._add_option('persistdir', PathOption(dnf.const.PERSISTDIR)) # :api
        self._add_option('transformdb', BoolOption(True))  # :api
        self._add_option('recent', IntOption(7, range_min=0))
        self._add_option('retries', PositiveIntOption(10, names_of_0=["0"]))
        self._add_option('reset_nice', BoolOption(True))

        self._add_option('cachedir', PathOption(cachedir)) # :api
        self._add_option('system_cachedir',
                         PathOption(dnf.const.SYSTEM_CACHEDIR)) # :api
        self._add_option('cacheonly', BoolOption(False))

        self._add_option('keepcache', BoolOption(False))
        self._add_option('logdir', Option(logdir)) # :api
        self._add_option('reposdir', ListOption(['/etc/yum.repos.d',
                                                 '/etc/yum/repos.d',
                                                 '/etc/distro.repos.d'])) # :api

        self._add_option('debug_solver', BoolOption(False))

        self._add_option('excludepkgs', ListAppendOption())
        self._add_option('includepkgs', ListAppendOption())
        self._add_option('exclude', self._get_option('excludepkgs'))
            # ^ compatibility with yum
        self._add_option('fastestmirror', BoolOption(False))
        self._add_option('proxy', UrlOption(schemes=('http', 'ftp', 'https',
                                                     'socks5', 'socks5h',
                                                     'socks4', 'socks4a'),
                                            allow_none=True)) # :api
        self._add_option('proxy_username', Option()) # :api
        self._add_option('proxy_password', Option()) # :api
        self._add_option('protected_packages',
                         ListOption("dnf glob:/etc/yum/protected.d/*.conf " \
                                    "glob:/etc/dnf/protected.d/*.conf")) #:api
        self._add_option('username', Option()) # :api
        self._add_option('password', Option()) # :api
        self._add_option('installonlypkgs', ListAppendOption(dnf.const.INSTALLONLYPKGS))
        self._add_option('group_package_types', ListOption(dnf.const.GROUP_PACKAGE_TYPES))
            # NOTE: If you set this to 2, then because it keeps the current
            # kernel it means if you ever install an "old" kernel it'll get rid
            # of the newest one so you probably want to use 3 as a minimum
            # ... if you turn it on.
        self._add_option('installonly_limit',
                         PositiveIntOption(3, range_min=2, names_of_0=["0", "<off>"]))  # :api
        self._add_option('tsflags', ListAppendOption())  # :api

        self._add_option('assumeyes', BoolOption(False)) # :api
        self._add_option('assumeno', BoolOption(False))
        self._add_option('check_config_file_age', BoolOption(True))
        self._add_option('defaultyes', BoolOption(False))
        self._add_option('diskspacecheck', BoolOption(True))
        self._add_option('gpgcheck', BoolOption(False))
        self._add_option('repo_gpgcheck', BoolOption(False))
        self._add_option('localpkg_gpgcheck', BoolOption(False))
        self._add_option('obsoletes', BoolOption(True))
        self._add_option('showdupesfromrepos', BoolOption(False))
        self._add_option('enabled', BoolOption(True))
        self._add_option('enablegroups', BoolOption(True))
        self._add_option('exit_on_lock', BoolOption(False))

        self._add_option('bandwidth', BytesOption(0))
        self._add_option('minrate', BytesOption(1000))
        self._add_option('ip_resolve',
                         CaselessSelectionOption(choices=('ipv4', 'ipv6',
                                                          'whatever'),
                                                 mapper={'4': 'ipv4',
                                                         '6': 'ipv6'}))
        self._add_option('throttle', ThrottleOption(0))
        self._add_option('timeout', SecondsOption(30))
        self._add_option('max_parallel_downloads', IntOption(None, range_min=1))

        self._add_option('metadata_expire',
                         SecondsOption(60 * 60 * 48))    # 48 hours
        self._add_option('metadata_timer_sync',
                         SecondsOption(60 * 60 * 3)) #  3 hours
        self._add_option('disable_excludes', ListOption())
        self._add_option('multilib_policy',
                         SelectionOption('best', choices=('best', 'all'))) # :api
        self._add_option('best', BoolOption(False)) # :api
        self._add_option('install_weak_deps', BoolOption(True))
        self._add_option('bugtracker_url', Option(dnf.const.BUGTRACKER))

        self._add_option('color',
                         SelectionOption('auto',
                                         choices=('auto', 'never', 'always'),
                                         mapper={'on': 'always', 'yes' : 'always',
                                                 '1' : 'always', 'true': 'always',
                                                 'off': 'never', 'no':   'never',
                                                 '0':   'never', 'false': 'never',
                                                 'tty': 'auto', 'if-tty': 'auto'})
                        )
        self._add_option('color_list_installed_older', Option('bold'))
        self._add_option('color_list_installed_newer', Option('bold,yellow'))
        self._add_option('color_list_installed_reinstall', Option('normal'))
        self._add_option('color_list_installed_extra', Option('bold,red'))
        self._add_option('color_list_available_upgrade', Option('bold,blue'))
        self._add_option('color_list_available_downgrade', Option('dim,cyan'))
        self._add_option('color_list_available_reinstall',
                         Option('bold,underline,green'))
        self._add_option('color_list_available_install', Option('normal'))
        self._add_option('color_update_installed', Option('normal'))
        self._add_option('color_update_local', Option('bold'))
        self._add_option('color_update_remote', Option('normal'))
        self._add_option('color_search_match', Option('bold'))

        self._add_option('sslcacert', PathOption()) # :api
        self._add_option('sslverify', BoolOption(True)) # :api
        self._add_option('sslclientcert', Option()) # :api
        self._add_option('sslclientkey', Option()) # :api
        self._add_option('deltarpm', BoolOption(True))
        self._add_option('deltarpm_percentage',
                         PositiveIntOption(75, names_of_0=["0", "<off>"]))

        self._add_option('history_record', BoolOption(True))
        self._add_option('history_record_packages', ListOption(['dnf', 'rpm']))

        self._add_option('rpmverbosity', Option('info'))
        self._add_option('strict', BoolOption(True)) # :api
        self._add_option('skip_broken', BoolOption(False))  # :yum-compatibility
        self._add_option('autocheck_running_kernel', BoolOption(True))  # :yum-compatibility
        self._add_option('clean_requirements_on_remove', BoolOption(True))
        self._add_option('history_list_view',
                         SelectionOption('commands',
                                         choices=('single-user-commands',
                                                  'users', 'commands'),
                                         mapper={'cmds': 'commands',
                                                 'default': 'commands'}))
        self._add_option('upgrade_group_objects_upgrade',
                         BoolOption(True))  # :api
        self._add_option('destdir', PathOption(None))
        self._add_option('comment', Option())
        # runtime only options
        self._add_option('downloadonly', BoolOption(False, runtimeonly=True))
        self._add_option('ignorearch', BoolOption(False))
        self._add_option('cacheonly', BoolOption(False))

    @property
    def get_reposdir(self):
        # :api
        """Returns the value of reposdir"""
        myrepodir = None
        # put repo file into first reposdir which exists or create it
        for rdir in self._get_value('reposdir'):
            if os.path.exists(rdir):
                myrepodir = rdir
                break

        if not myrepodir:
            myrepodir = self._get_value('reposdir')[0]
            dnf.util.ensure_dir(myrepodir)
        return myrepodir

    def _search_inside_installroot(self, optname):
        opt = self._get_option(optname)
        prio = opt._get_priority()
        # dont modify paths specified on commandline
        if prio >= PRIO_COMMANDLINE:
            return
        val = opt._get()
        # if it exists inside installroot use it (i.e. adjust configuration)
        # for lists any component counts
        if isinstance(val, list):
            if any(os.path.exists(os.path.join(self._get_value('installroot'),
                                               p.lstrip('/')))
                   for p in val):
                opt._set(Value([self._prepend_installroot_path(p) for p in val],
                               prio))
        elif os.path.exists(os.path.join(self._get_value('installroot'),
                                         val.lstrip('/'))):
            self.prepend_installroot(optname)
            opt._set(Value(self._prepend_installroot_path(val), prio))

    def prepend_installroot(self, optname):
        # :api
        opt = self._get_option(optname)
        prio = opt._get_priority()
        new_path = self._prepend_installroot_path(opt._get())
        opt._set(Value(new_path, prio))

    def _prepend_installroot_path(self, path):
        root_path = os.path.join(self._get_value('installroot'), path.lstrip('/'))
        return dnf.conf.parser.substitute(root_path, self.substitutions)

    def _configure_from_options(self, opts):
        """Configure parts of CLI from the opts """
        config_args = ['plugins', 'version', 'config_file_path',
                       'debuglevel', 'errorlevel', 'installroot',
                       'best', 'assumeyes', 'assumeno', 'clean_requirements_on_remove', 'gpgcheck',
                       'showdupesfromrepos', 'plugins', 'ip_resolve',
                       'rpmverbosity', 'disable_excludes', 'color',
                       'downloadonly', 'exclude', 'excludepkgs', 'skip_broken',
                       'tsflags', 'arch', 'basearch', 'ignorearch', 'cacheonly', 'comment']

        for name in config_args:
            value = getattr(opts, name, None)
            if value is not None and value != []:
                confopt = self._get_option(name)
                if confopt:
                    confopt._set(value, dnf.conf.PRIO_COMMANDLINE)
                elif hasattr(self, name):
                    setattr(self, name, value)
                else:
                    logger.warning(_('Unknown configuration option: %s = %s'),
                                   ucd(name), ucd(value))

        if hasattr(opts, 'main_setopts'):
            # now set all the non-first-start opts from main from our setopts
            # pylint: disable=W0212
            for name, val in opts.main_setopts._get_kwargs():
                opt = self._get_option(name)
                if opt:
                    opt._set(val, dnf.conf.PRIO_COMMANDLINE)
                elif hasattr(self, name):
                    setattr(self, name, val)
                else:
                    msg = "Main config did not have a %s attr. before setopt"
                    logger.warning(msg, name)

    def exclude_pkgs(self, pkgs):
        # :api
        name = "excludepkgs"

        if pkgs is not None and pkgs != []:
            confopt = self._get_option(name)
            if confopt:
                confopt._set(pkgs, dnf.conf.PRIO_COMMANDLINE)
            else:
                logger.warning(_('Unknown configuration option: %s = %s'),
                               ucd(name), ucd(pkgs))

    def _adjust_conf_options(self):
        """Adjust conf options interactions"""

        skip_broken = self._get_option('skip_broken')
        skip_broken_val = skip_broken._get()
        if skip_broken_val:
            strict = self._get_option('strict')
            strict._set(not skip_broken_val, skip_broken._get_priority())

    @property
    def releasever(self):
        # :api
        return self.substitutions.get('releasever')

    @releasever.setter
    def releasever(self, val):
        # :api
        if val is None:
            self.substitutions.pop('releasever', None)
            return
        self.substitutions['releasever'] = val

    @property
    def arch(self):
        # :api
        return self.substitutions.get('arch')

    @arch.setter
    def arch(self, val):
        # :api

        if val is None:
            self.substitutions.pop('arch', None)
            return
        if val not in dnf.rpm._BASEARCH_MAP.keys():
            msg = _('Incorrect or unknown "{}": {}')
            raise dnf.exceptions.Error(msg.format("arch", val))
        self.substitutions['arch'] = val
        self.basearch = dnf.rpm.basearch(val)

    @property
    def basearch(self):
        # :api
        return self.substitutions.get('basearch')

    @basearch.setter
    def basearch(self, val):
        # :api

        if val is None:
            self.substitutions.pop('basearch', None)
            return
        if val not in dnf.rpm._BASEARCH_MAP.values():
            msg = _('Incorrect or unknown "{}": {}')
            raise dnf.exceptions.Error(msg.format("basearch", val))
        self.substitutions['basearch'] = val

    def read(self, filename=None, priority=PRIO_DEFAULT):
        # :api
        if filename is None:
            filename = self._get_value('config_file_path')
        self._parser = ConfigParser()
        config_pp = dnf.conf.parser.ConfigPreProcessor(filename)
        try:
            self._parser.readfp(config_pp)
        except ParsingError as e:
            raise dnf.exceptions.ConfigError("Parsing file failed: %s" % e)
        self._populate(self._parser, self._section, filename, priority)

        # update to where we read the file from
        self._set_value('config_file_path', filename, priority)

    @property
    def verbose(self):
        return self._get_value('debuglevel') >= dnf.const.VERBOSE_LEVEL