-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
zypper_repository: preserve attributes enabled, autorefresh and gpgcheck if provided from the task parameters #9108
base: main
Are you sure you want to change the base?
Conversation
… parameters Currently, the values are overridden with the data found on the file system Instead, these values should only be updated, if they were not provided in the parameters. That way, repositories on the system could be enabled/disabled and the flags could be updated again
if the values are not provided from the task-input nor read from an existing file
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.
Thanks for your contribution! I've added some first comments.
plugins/modules/zypper_repository.py
Outdated
if module.params['autorefresh']: | ||
repodata['autorefresh'] = '1' | ||
else: | ||
repodata['autorefresh'] = '0' |
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.
module.params
always contains all possible module options, so 'xxx' in module.params
will always evaluate to True
(if xxx
is a valid module option). Also these three options have defaults, so even if the user did not provide them, they will always be set to their default value in module.params
.
If you want to test whether the values have been provided by the user or not, you need to remove the defaults, and check for None
instead (like if module.params['autorefresh'] is not None:
).
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.
Interesting. I thought, I had tested it locally and adding the condition works. I'll give this another try and I'll also try to add some tests
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.
On the other hand I think this might break the logic where the plugin compares the configuration passed via module.params against what is found on the file system - not passing a value might result in the code detecting a change in configuration....
Also: is this the default behaviour in ansible-modules: not passing a parameter that has a default configured will change an existing configuration that was configured against the default value? That's something, I wouldn't expect
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.
Also: is this the default behaviour in ansible-modules: not passing a parameter that has a default configured will change an existing configuration that was configured against the default value? That's something, I wouldn't expect
That depends on whether options have a default value or not. Having a default for options that are used for idempotency checks have this side-effect, which is usually not what the user wants. That's why it's best to only have default values for options that are not used for idempotency check, but never have defaults for options that are used for idempotency checks. (Unless there are very good reasons for a specific option; which can happen, but is not very likely.)
To fix this, it's usually best to remove the default values, and change the code so that if the user does not provide the option, the old default value is used when something is created.
Also please note that you are changing the behavior of the module, as I understand it, which is a breaking change. You need to control the behavior by a new option so that existing tasks will behave exactly as before.
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.
module.params
always contains all possible module options, so'xxx' in module.params
will always evaluate toTrue
(ifxxx
is a valid module option). Also these three options have defaults, so even if the user did not provide them, they will always be set to their default value inmodule.params
.
I beg to differ, @felixfontein . If the value of the parameter is None
, then that stmt is equivalent to if None:
, which evaluates to False
. He's not checking whether the parameter exists, he is using the parameter value, and None
is... False
-ish.
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.
The statement if 'xxx' in module.params:
is not equivalent to if None
if module.params['xxx']
is None
.
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.
You're right of course. I was mislead by the fact that the lines of code selected for this comment do not include that part. Re-reading I see I missed some bits, and I have even submitted a suggestion fixing that up.
changelogs/fragments/8783-preserve-parameters-provided-from-task-in-zypper-module.yaml
Outdated
Show resolved
Hide resolved
I think, this is the right approach: # fill the boolean entries with default # override the values with what is found in the repo-file (remote or locally on the file) # finally override the values with what is provided in the module-params then we can check if the data has changed compared to the local data
I had copied and edited the data but not saved the changes
adding tests: * modifying a repository should work (disabling) * modifying a different parameter doesn't change configuation that was not specified - although it has a different default-value, than what is currenctly configured
@@ -0,0 +1,2 @@ | |||
bugfixes: | |||
- zypper-module - only read attributes ``enabled``, ``disable_gpg_check`` and ``autorefresh`` from local repo files, if the parameters weren't already provided by the task parameters |
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.
- zypper-module - only read attributes ``enabled``, ``disable_gpg_check`` and ``autorefresh`` from local repo files, if the parameters weren't already provided by the task parameters | |
- zypper-module - only read attributes ``enabled``, ``disable_gpg_check`` and ``autorefresh`` from local repo files, if the parameters were not already provided by the task parameters (https://github.com/ansible-collections/community.general/pull/9108). |
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.
Hi @TobiasZeuch181 please add this modification as well.
plugins/modules/zypper_repository.py
Outdated
if module.params['autorefresh']: | ||
repodata['autorefresh'] = '1' | ||
else: | ||
repodata['autorefresh'] = '0' |
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.
Also: is this the default behaviour in ansible-modules: not passing a parameter that has a default configured will change an existing configuration that was configured against the default value? That's something, I wouldn't expect
That depends on whether options have a default value or not. Having a default for options that are used for idempotency checks have this side-effect, which is usually not what the user wants. That's why it's best to only have default values for options that are not used for idempotency check, but never have defaults for options that are used for idempotency checks. (Unless there are very good reasons for a specific option; which can happen, but is not very likely.)
To fix this, it's usually best to remove the default values, and change the code so that if the user does not provide the option, the old default value is used when something is created.
Also please note that you are changing the behavior of the module, as I understand it, which is a breaking change. You need to control the behavior by a new option so that existing tasks will behave exactly as before.
Co-authored-by: Alexei Znamensky <[email protected]>
Other than the small detail in the changelog fragment, LGTM |
if 'enabled' in module.params: | ||
if module.params['enabled']: | ||
repodata['enabled'] = '1' | ||
else: | ||
repodata['enabled'] = '0' | ||
if 'disable_gpg_check' in module.params: | ||
if module.params['disable_gpg_check']: | ||
repodata['gpgcheck'] = '0' | ||
else: | ||
repodata['gpgcheck'] = '1' | ||
if 'autorefresh' in module.params: | ||
if module.params['autorefresh']: | ||
repodata['autorefresh'] = '1' | ||
else: | ||
repodata['autorefresh'] = '0' |
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 check if the key exists, however, is redundant. They will always exist. Please simplify this to:
if 'enabled' in module.params: | |
if module.params['enabled']: | |
repodata['enabled'] = '1' | |
else: | |
repodata['enabled'] = '0' | |
if 'disable_gpg_check' in module.params: | |
if module.params['disable_gpg_check']: | |
repodata['gpgcheck'] = '0' | |
else: | |
repodata['gpgcheck'] = '1' | |
if 'autorefresh' in module.params: | |
if module.params['autorefresh']: | |
repodata['autorefresh'] = '1' | |
else: | |
repodata['autorefresh'] = '0' | |
repodata['enabled'] = '1' if module.params['enabled'] else '0' | |
repodata['gpgcheck'] = '0' if module.params['disable_gpg_check'] else '1' | |
repodata['autorefresh'] = '1' if module.params['autorefresh'] else '0' |
… task parameters
Currently, the values are overridden with the data found on the file system Instead, these values should only be updated, if they were not provided in the parameters. That way, repositories on the system could be enabled/disabled and the flags could be updated again
SUMMARY
The code currently looks up the repo-file on the local disk and if it exists, it load the optional attributes
enabled
,autorefresh
andgpgcheck
and these values are used to fill up the repository-object that is later written to disk.Unfortunately, these values are overriding the attributes, if they were provided from the task in ansible - which makes it impossible to modify the values for a repository that is already registered on the system.
So I changed the code, to:
I considered changing the order of the statements to
but I thought it was better to stay with the current structure, because the change is smaller and we need the code to read the ansible-parameters at the beginning to check, if there parameters would introduce a change.
Fixes 8783
ISSUE TYPE
COMPONENT NAME
zupper_repository
ADDITIONAL INFORMATION