Skip to content
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

Improve error condition handling for dnf module #44770

Merged
merged 1 commit into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 24 additions & 6 deletions lib/ansible/module_utils/yumdnf.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,30 @@ def __init__(self, module):

# It's possible someone passed a comma separated string since it used
# to be a string type, so we should handle that
if self.enablerepo and len(self.enablerepo) == 1 and ',' in self.enablerepo:
self.enablerepo = self.module.params['enablerepo'].split(',')
if self.disablerepo and len(self.disablerepo) == 1 and ',' in self.disablerepo:
self.disablerepo = self.module.params['disablerepo'].split(',')
if self.exclude and len(self.exclude) == 1 and ',' in self.exclude:
self.exclude = self.module.params['exclude'].split(',')
self.names = self.listify_comma_sep_strings_in_list(self.names)
self.disablerepo = self.listify_comma_sep_strings_in_list(self.disablerepo)
self.enablerepo = self.listify_comma_sep_strings_in_list(self.enablerepo)
self.exclude = self.listify_comma_sep_strings_in_list(self.exclude)

def listify_comma_sep_strings_in_list(self, some_list):
"""
method to accept a list of strings as the parameter, find any strings
in that list that are comma separated, remove them from the list and add
their comma separated elements to the original list
"""
new_list = []
remove_from_original_list = []
for element in some_list:
if ',' in element:
remove_from_original_list.append(element)
new_list.extend([e.strip() for e in element.split(',')])

for element in remove_from_original_list:
some_list.remove(element)

some_list.extend(new_list)

return some_list

@abstractmethod
def run(self):
Expand Down
25 changes: 22 additions & 3 deletions lib/ansible/modules/packaging/os/dnf.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,16 @@ def __init__(self, module):

self._ensure_dnf()

def _sanitize_dnf_error_msg(self, spec, error):
"""
For unhandled dnf.exceptions.Error scenarios, there are certain error
messages we want to filter. Do that here.
"""
if to_text("no package matched") in to_text(error):
return "No package {0} available.".format(spec)

return error

def _package_dict(self, package):
"""Return a dictionary of information for the package."""
# NOTE: This no longer contains the 'dnfstate' field because it is
Expand Down Expand Up @@ -856,7 +866,9 @@ def ensure(self):
install_result = self._mark_package_install(pkg_spec)
if install_result['failed']:
failure_response['msg'] += install_result['msg']
failure_response['failures'].append(install_result['failure'])
failure_response['failures'].append(self._sanitize_dnf_error_msg(pkg_spec, install_result['failure']))
else:
response['results'].append(install_result['msg'])

elif self.state == 'latest':
# "latest" is same as "installed" for filenames.
Expand Down Expand Up @@ -901,7 +913,9 @@ def ensure(self):
install_result = self._mark_package_install(pkg_spec, upgrade=True)
if install_result['failed']:
failure_response['msg'] += install_result['msg']
failure_response['failures'].append(install_result['failure'])
failure_response['failures'].append(self._sanitize_dnf_error_msg(pkg_spec, install_result['failure']))
else:
response['results'].append(install_result['msg'])

else:
# state == absent
Expand Down Expand Up @@ -1075,7 +1089,12 @@ def main():
try:
module_implementation.run()
except dnf.exceptions.RepoError as de:
module.exit_json(msg="Failed to synchronize repodata: {0}".format(to_native(de)))
module.fail_json(
msg="Failed to synchronize repodata: {0}".format(to_native(de)),
rc=1,
results=[],
changed=False
)


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion test/integration/targets/dnf/tasks/dnf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@
that:
- "dnf_result is failed"
- "'non-existent-rpm' in dnf_result['failures'][0]"
- "'no package matched' in dnf_result['failures'][0]"
- "'No package non-existent-rpm available' in dnf_result['failures'][0]"
- "'Failed to install some of the specified packages' in dnf_result['msg']"

- name: use latest to install httpd
Expand Down