From d9bd76dc8a58a278eaf0036361348825e649bf1e Mon Sep 17 00:00:00 2001 From: Sam Doran Date: Wed, 12 Sep 2018 17:45:45 -0400 Subject: [PATCH] Improve code stability is checksum checking - use context manager for dealing with the checksum file - use loop that can tolerate zero, one, or more items return rather than the previous expression which would break if anything other than exactly one item was returned (cherry picked from commit 03dbb1d9c45312d6723c687c92c00013454b959a) squash --- .../fragments/get_url-remove-fragile-code.yaml | 2 ++ lib/ansible/modules/net_tools/basics/get_url.py | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/get_url-remove-fragile-code.yaml diff --git a/changelogs/fragments/get_url-remove-fragile-code.yaml b/changelogs/fragments/get_url-remove-fragile-code.yaml new file mode 100644 index 00000000000..ab997c576cc --- /dev/null +++ b/changelogs/fragments/get_url-remove-fragile-code.yaml @@ -0,0 +1,2 @@ +bugfixes: + - get_url - improve code that parses checksums from a file so it is not fragile and reports a helpful error when no matching checksum is found diff --git a/lib/ansible/modules/net_tools/basics/get_url.py b/lib/ansible/modules/net_tools/basics/get_url.py index eb63a5791fa..53c79536a45 100644 --- a/lib/ansible/modules/net_tools/basics/get_url.py +++ b/lib/ansible/modules/net_tools/basics/get_url.py @@ -445,11 +445,22 @@ def main(): checksum_url = checksum # download checksum file to checksum_tmpsrc checksum_tmpsrc, checksum_info = url_get(module, checksum_url, dest, use_proxy, last_mod_time, force, timeout, headers, tmp_dest) - lines = [line.rstrip('\n') for line in open(checksum_tmpsrc)] + with open(checksum_tmpsrc) as f: + lines = [line.rstrip('\n') for line in f] os.remove(checksum_tmpsrc) lines = dict(s.split(None, 1) for s in lines) filename = url_filename(url) - [checksum] = (k for (k, v) in lines.items() if v.strip('./') == filename) + + # Look through each line in the checksum file for a hash corresponding to + # the filename in the url, returning the first hash that is found. + for cksum in (s for (s, f) in lines.items() if f.strip('./') == filename): + checksum = cksum + break + else: + checksum = None + + if checksum is None: + module.fail_json("Unable to find a checksum for file '%s' in '%s'" % (filename, checksum_url)) # Remove any non-alphanumeric characters, including the infamous # Unicode zero-width space checksum = re.sub(r'\W+', '', checksum).lower()