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 0000000000..ab997c576c --- /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 eb63a5791f..53c79536a4 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()