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
config: T5228: simplify get_config_dict and add argument with_defaults #2010
Conversation
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 like the idea to simplify getting a config with defaults.
However, I feel that such functionality should come with clear guidelines on how to use it properly. Possibly even with safeguards that ensure that it doesn't get in the way.
Here's the infamous...
Problem of defaults
When there is no such thing as a first-class default value in interface definitions, there are only two cases:
- Config node exists and has a value (unless it's valueless).
- Config node doesn't exist.
That means that "node doesn't exist in the config dict = node doesn't exist in the config".
First-class defaults come comes at a pretty dire price: existence of a node in the config dict no longer means that it exists in the config itself! It may now mean two things: either that node exists in the config or it simply has a default value.
For values with defaults, it becomes impossible to check if they actually exist or not.
In the old config system where $config->returnValue()
would return the default value for nodes that had it, whether they were actually present in the config or not, that created an impassable obstacle to implementing live rollbacks: it made node deletion impossible to detect and thus an inverse of a diff was also impossible to reconstruct.
Now we are getting a light version of that problem. "Light" in that we do have a way to check if a node exists in the config or not.
Config scripts must never use config dicts with defaults for verification because they create an impression that subtrees exist but don't have required options — just because an option in a subtree has a default value. Templates can also get troubles with it.
Possible solution
I'm now thinking that there's one invariant that can save us from the problem of defaults: defaults must never be injected in a subtree whose parent doesn't exist in the config.
In different words: default value for a node must be injected if and only if its parent exists in the config tree.
I don't have a proof that it's sufficient yet but my feeling is that it should be.
The PR version satisfies the invariant 'defaults of paths (without intervening unspecified tag nodes) are added only if an ancestor exists in the config'. We can choose to only add leaf nodes whose parent is set in the config, which would rule out, say, the recent issue with VRRP 'health-check' (T5215; commit 00b48df); example below. This would correspond with the hypothesis that an intervening non-leaf node would indicate an intentional effect; whether that is always the case is an open question. I will add an arg 'recursive=False' to the Current PR version is recursive from ancestor along paths not containing an unspecified tag node:
|
6d747e5
to
da74a0b
Compare
The base PR for these simplifications The non-local behavior is accessible with the explicit functions
|
da74a0b
to
c0f8e73
Compare
73820e1
to
4b5b732
Compare
Temporarily set to draft to fix bug in recursive option. |
dd01d94
to
a682c6b
Compare
Fixed regression caused by introduction of option |
a682c6b
to
499adc9
Compare
For those cases not covered by automatic merging of defaults in get_config_dict(..., with_defaults=True), get_config_defaults should take arguments consistent with those of get_config_dict, for ease of merging results.
499adc9
to
d19e7e5
Compare
Note that this is a dependency for #2052, which has been merged; merging now. |
Change Summary
After T5218, we can simplify the key_mangling function used by get_config_dict, and add an argument
get_config_dict(..., with_defaults=True)
to correctly merge default values.
Types of changes
Related Task(s)
Component(s) name
Proposed changes
How to test
Checklist: