-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for drop-in configuration directories #813
Add support for drop-in configuration directories #813
Conversation
This solution uses a fixed list of drop-in directories. The file loading order algorithm is inspired by So it is a competing implementation to PR #741. Competing PR introduces support for including configuration files using a special comment directive in the configuration file. Note to reviewer: |
Just a question - does it still make sense to have separate |
I'm trying to understand this order, does this mean that DNF basically stops reading config if |
@Conan-Kudo "libeconf" https://github.com/openSUSE/libeconf does a similar thing. |
Which configuration among dnf.conf and libdnf5.conf.d take precedence? |
@Conan-Kudo |
@ppisar |
I plan that configuration changes made by |
That makes sense. So how will this extend to repo configuration? Because that's the big one that both Fedora and openSUSE would like to solve too. |
This PR only addresses loading the libdnf configuration. The "[main]" section in the configuration files. What about repositories configuration? So far I have this idea:"libdnf5" now loads repositories configuration from We can: In any case, this would be to support overwriting the configuration of existing repositories. Creating new repositories using these drop-in directories will not be supported. I am considering glob support for bulk modification of repositories parameters.
But those are just my ideas. I don't know yet what I will implement or how we will agree in the team. |
So, in openSUSE, we have the following repo dirs: Packaged configs go in the latter two directories, whereas the first path is where user-installed ones go. I would like to change this to have packaged repository configs move to This would also include moving the packaged GPG keys to So the idea would be to have For user-controlled things, in addition to the existing directory paths in |
@Conan-Kudo In my description above it was about the introduction of "overrides". That is, configuration files that will not be able to define new repositories, but only modify existing ones. But we are already running outside the scope of this PR. It handles the main configuration of libdnf (the "[main]" section). No repositories configuration. |
I'm not sure. I'd leave it as is for now. |
6b6781b
to
aa5640c
Compare
libdnf5/base/base.cpp
Outdated
|
||
// If the name of the configuration file was not specified, the files from the drop-in directories are also loaded. | ||
// An alphabetically sorted list of all configuration files from the drop-in directories is created. If there is | ||
// a file of the same name in both the user and distribution drop-in directories, only the user file is used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about this logic. If user will specify -C /, then all distribution and /etc overrides will be ignored. May I ask you for more details or some use case when this behavior is beneficial?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is important to resolve
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@j-mracek
-C, --cacheonly
You probably meant -c [config file], --config [config file]
. Not yet implemented in dnf5. So -c user_config_file
.
What should I do? The user has explicitly specified that they want configuration from this file. Overwriting it with configuration from drop-in directories is probably not what he wants. Therefore, in this case, the configuration from the drop-in directories is not loaded.
A compromise can still be made in this case. Change loading order. Load configuration files from drop-in directories and then from an explicitly user-defined file. But it will be so weird. The user changes the path to the main configuration file, but not the path to the drop-in directories.
aa5640c
to
9dcccde
Compare
Drop in configuration must be also documented in |
Notes from discussion: RequirementsWhen user specify configuration files, it should be not overridden by drop in configuration Solutions
|
I would prefer to use Solution 2 - |
@keszybz May I ask you for your opinion? |
I agree with the requirement that a user's configuration has a higher priority / is loaded later than a distribution-wide configuration. As a side note, I think that introducing configuration locations of various priorities is not much helpful: Instead of fighting over a line number in a single configuration file, users and packagers will fight over the highest file name. Therefore I'd like to decrease the amount of various locations to a bare minimum. I understand that configuration directories are easier for populating by third-parties than editing a single file. Therefore I recommend removing a distribution-wide file /usr/share/dnf5/libdnf.conf completely. Regarding /etc/dnf/dnf.conf file, I would discourage user's from using it. The only remaining function of it would be a backward compatibility and a last resort place with guaranteed hightest priority. |
I think we will need to implement inhibition of system-wide configuration for DNF5 tests. |
9dcccde
to
f75e3d5
Compare
Based on discussions in the team, I changed the loading order of the configuration files. I also edited the description accordingly. |
f75e3d5
to
d62f669
Compare
include/libdnf5/base/base.hpp
Outdated
/// Call a function that loads the config file, catching errors appropriately | ||
void with_config_file_path(std::function<void(const std::string &)> func); | ||
|
||
/// Loads main configuration from file defined by the current configuration. | ||
/// @deprecated It will be removed in Fedora 40. It is redundant. It calls `load_config()`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposing to remove It will be removed in Fedora 40
, because the removal will have negative consequences on multiple projects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@j-mracek OK, removed.
Introduces a new method `Base::load_config()` to replace `Base::load_config_from_file()`. In the original implementation, the `Base` class constructor loads the default configuration from the distribution configuration file ("/usr/share/dnf5/libdnf.conf"). And later, the user configuration (by default "/etc/dnf/dnf.conf") was loaded by calling the `Base::load_config_from_file()` method. New implementation: 1. The `Base` class constructor does not load any configuration file. 2. The application calls `Base::load_config()` method instead of `Base::load_config_from_file()`. The order of loading the configuration files by the method `Base::load_config()`: 1. Creates an alphabetically sorted list of names of configuration files in the distribution configuration drop-in directory ("/usr/share/dnf5/libdnf.conf.d") and the user configuration drop-in directory ("/etc/dnf/libdnf5.conf.d"). If the file with the same name is present in both drop-in directories, only the file from the user configuration drop-in directory is added to the sorted list. So, the distribution configuration drop-in file can be simply masked by creating a file with the same name in the user configuration drop-in directory. 2. Retrieves the configuration from the files in the sorted list. Follows the order. The configuration from the next file overrides the previous one - the last option value wins. 3. Loads the user configuration file (by default "/etc/dnf/dnf.conf"), if exists. If file does not exist and was explicitly requested by the user, the method throws an exeption. --------------------------------------------- Example configuration: User configuration files: /etc/dnf/dnf.conf /etc/dnf/libdnf5.conf.d/20-user-settings.conf /etc/dnf/libdnf5.conf.d/60-something.conf /etc/dnf/libdnf5.conf.d/80-user-settings.conf Distribution configuration files: /usr/share/dnf5/libdnf.conf.d/50-something.conf /usr/share/dnf5/libdnf.conf.d/60-something.conf /usr/share/dnf5/libdnf.conf.d/90-something.conf Resulting file loading order by default ("/usr/share/dnf5/libdnf.conf.d/60-something.conf" is skipped, masked by the user file "/etc/dnf/libdnf5.conf.d/60-something.conf"): 1. /etc/dnf/libdnf5.conf.d/20-user-settings.conf 2. /usr/share/dnf5/libdnf.conf.d/50-something.conf 3. /etc/dnf/libdnf5.conf.d/60-something.conf 4. /etc/dnf/libdnf5.conf.d/80-user-settings.conf 5. /usr/share/dnf5/libdnf.conf.d/90-something.conf 6. /etc/dnf/dnf.conf
d62f669
to
2f39d84
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Failed tests looks like not related to PR. |
Is this now the status quo?
If files are loaded in this exact order, then |
DNF5 component will ship only empty |
Introduces a new method
Base::load_config()
to replaceBase::load_config_from_file()
.In the original implementation, the
Base
class constructor loads the default configuration from the distribution configuration file ("/usr/share/dnf5/libdnf.conf"). And later, the user configuration (by default "/etc/dnf/dnf.conf") was loaded by calling theBase::load_config_from_file()
method.New implementation:
Base
class constructor does not load any configuration file.Base::load_config()
method instead ofBase::load_config_from_file()
.The order of loading the configuration files by the method
Base::load_config()
:Example configuration:
User configuration files:
/etc/dnf/dnf.conf
/etc/dnf/libdnf5.conf.d/20-user-settings.conf
/etc/dnf/libdnf5.conf.d/60-something.conf
/etc/dnf/libdnf5.conf.d/80-user-settings.conf
Distribution configuration files:
/usr/share/dnf5/libdnf.conf.d/50-something.conf
/usr/share/dnf5/libdnf.conf.d/60-something.conf
/usr/share/dnf5/libdnf.conf.d/90-something.conf
Resulting file loading order by default
("/usr/share/dnf5/libdnf.conf.d/60-something.conf" is skipped, masked by the user file "/etc/dnf/libdnf5.conf.d/60-something.conf"):