From 79bb7bde5ff447d7734a93f0d8b5c248f117dd6a Mon Sep 17 00:00:00 2001 From: Kevin Backhouse Date: Wed, 29 May 2019 20:59:51 +0100 Subject: [PATCH] apt_repository: Fix crash caused by cache.update() raising an IOError on timeout. (#51996) * Fix crash caused by cache.update() raising an IOError on timeout. * Add changelog fragment. --- .../51995-apt_repository-catch-IOError.yaml | 2 ++ lib/ansible/modules/packaging/os/apt_repository.py | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/51995-apt_repository-catch-IOError.yaml diff --git a/changelogs/fragments/51995-apt_repository-catch-IOError.yaml b/changelogs/fragments/51995-apt_repository-catch-IOError.yaml new file mode 100644 index 00000000000..5a2882cf529 --- /dev/null +++ b/changelogs/fragments/51995-apt_repository-catch-IOError.yaml @@ -0,0 +1,2 @@ +bugfixes: + - apt_repository - Fix crash caused by ``cache.update()`` raising an ``IOError`` due to a timeout in ``apt update`` (https://github.com/ansible/ansible/issues/51995) diff --git a/lib/ansible/modules/packaging/os/apt_repository.py b/lib/ansible/modules/packaging/os/apt_repository.py index e6fa46a1f62..d3234a733ce 100644 --- a/lib/ansible/modules/packaging/os/apt_repository.py +++ b/lib/ansible/modules/packaging/os/apt_repository.py @@ -108,6 +108,7 @@ import os import re import sys import tempfile +import copy try: import apt @@ -515,6 +516,7 @@ def main(): else: module.fail_json(msg='Module apt_repository is not supported on target.') + sourceslist_before = copy.deepcopy(sourceslist) sources_before = sourceslist.dump() try: @@ -544,8 +546,16 @@ def main(): if update_cache: cache = apt.Cache() cache.update() - except OSError as err: - module.fail_json(msg=to_native(err)) + except (OSError, IOError) as err: + # Revert the sourcelist files to their previous state. + # First remove any new files that were created: + for filename in set(sources_after.keys()).difference(sources_before.keys()): + if os.path.exists(filename): + os.remove(filename) + # Now revert the existing files to their former state: + sourceslist_before.save() + # Return an error message. + module.fail_json(msg='apt cache update failed') module.exit_json(changed=changed, repo=repo, state=state, diff=diff)