diff --git a/AUTHORS b/AUTHORS index 95f0c94c2f..f82c487305 100644 --- a/AUTHORS +++ b/AUTHORS @@ -93,3 +93,4 @@ DNF CONTRIBUTORS Tomas Kasparek Vladan Kudlac Will Woods + Ondřej Sojka diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py index 09642d1eb1..fa30fcaf3f 100644 --- a/dnf/cli/cli.py +++ b/dnf/cli/cli.py @@ -870,6 +870,7 @@ def configure(self, args, option_parser=None): self.demands.cacheonly = True self.base.conf._configure_from_options(opts) self._read_conf_file(opts.releasever) + self.base.conf.read_dropin_dir() if 'arch' in opts: self.base.conf.arch = opts.arch self.base.conf._adjust_conf_options() diff --git a/dnf/conf/__init__.py b/dnf/conf/__init__.py index 77ba8ab94e..3ffe8ebd1a 100644 --- a/dnf/conf/__init__.py +++ b/dnf/conf/__init__.py @@ -24,8 +24,8 @@ places, hard to change and debug. The new structure here will replace that. Its goal is to: -* accept configuration options from all three sources (the main config file, - repo config files, command line switches) +* accept configuration options from all four sources (the main config file, + drop-in configuration folder, repo config files, command line switches) * handle all the logic of storing those and producing related values. * returning configuration values. * optionally: asserting no value is overridden once it has been applied diff --git a/dnf/conf/config.py b/dnf/conf/config.py index c6c1c57509..7e1782a2fb 100644 --- a/dnf/conf/config.py +++ b/dnf/conf/config.py @@ -42,6 +42,7 @@ PRIO_REPOCONFIG = libdnf.conf.Option.Priority_REPOCONFIG PRIO_PLUGINDEFAULT = libdnf.conf.Option.Priority_PLUGINDEFAULT PRIO_PLUGINCONFIG = libdnf.conf.Option.Priority_PLUGINCONFIG +PRIO_DROPINCONFIG = libdnf.conf.Option.Priority_DROPINCONFIG PRIO_COMMANDLINE = libdnf.conf.Option.Priority_COMMANDLINE PRIO_RUNTIME = libdnf.conf.Option.Priority_RUNTIME @@ -417,6 +418,10 @@ def read(self, filename=None, priority=PRIO_DEFAULT): # update to where we read the file from self._set_value('config_file_path', filename, priority) + def read_dropin_dir(self, dirname=dnf.const.CONF_DROPIN_DIR, priority=PRIO_DROPINCONFIG): + for filename in sorted(os.listdir(dirname)): + self.read(os.path.join(dirname, filename), priority) + @property def verbose(self): return self._get_value('debuglevel') >= dnf.const.VERBOSE_LEVEL diff --git a/dnf/const.py.in b/dnf/const.py.in index 4ef2613ec6..cdfed96718 100644 --- a/dnf/const.py.in +++ b/dnf/const.py.in @@ -23,6 +23,7 @@ import distutils.sysconfig CONF_FILENAME='/etc/dnf/dnf.conf' # :api CONF_AUTOMATIC_FILENAME='/etc/dnf/automatic.conf' +CONF_DROPIN_DIR='/etc/dnf/conf.d/' DISTROVERPKG=('system-release(releasever)', 'system-release', 'distribution-release(releasever)', 'distribution-release', 'redhat-release', 'suse-release') diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst index 6d0160d0d6..44970e0aa3 100644 --- a/doc/conf_ref.rst +++ b/doc/conf_ref.rst @@ -29,6 +29,11 @@ all \*.repo files found under ``/etc/yum.repos.d``. The latter is typically used for repository configuration and takes precedence over global configuration. +It is also possible to drop configuration snippets into ``/etc/dnf/conf.d/``. +These are read in alphabetical order and can override all configuration. Every +option must be part of a section to be read correctly; therefore start every +dropped-in configuration file with ``[main]`` or ``[repo]``. + The configuration file has INI format consisting of section declaration and ``name=value`` options below each on separate line. There are two types of sections in the configuration files: main and repository. Main section defines all global