diff --git a/changelogs/fragments/get-url-fix-idempotency.yaml b/changelogs/fragments/get-url-fix-idempotency.yaml new file mode 100644 index 00000000000..c09c6d8acda --- /dev/null +++ b/changelogs/fragments/get-url-fix-idempotency.yaml @@ -0,0 +1,2 @@ +bugfixes: +- get_url - Don't re-download files unnecessarily when force=no (https://github.com/ansible/ansible/issues/45491) diff --git a/lib/ansible/modules/net_tools/basics/get_url.py b/lib/ansible/modules/net_tools/basics/get_url.py index 5ec01817d3a..b8afb83ee17 100644 --- a/lib/ansible/modules/net_tools/basics/get_url.py +++ b/lib/ansible/modules/net_tools/basics/get_url.py @@ -466,18 +466,20 @@ def main(): if not force and checksum != '': destination_checksum = module.digest_from_file(dest, algorithm) - if checksum == destination_checksum: - # Not forcing redownload, unless checksum does not match - # allow file attribute changes - module.params['path'] = dest - file_args = module.load_file_common_arguments(module.params) - file_args['path'] = dest - changed = module.set_fs_attributes_if_different(file_args, False) - if changed: - module.exit_json(msg="file already exists but file attributes changed", dest=dest, url=url, changed=changed) - module.exit_json(msg="file already exists", dest=dest, url=url, changed=changed) + if checksum != destination_checksum: + checksum_mismatch = True - checksum_mismatch = True + # Not forcing redownload, unless checksum does not match + if not force and not checksum_mismatch: + # Not forcing redownload, unless checksum does not match + # allow file attribute changes + module.params['path'] = dest + file_args = module.load_file_common_arguments(module.params) + file_args['path'] = dest + changed = module.set_fs_attributes_if_different(file_args, False) + if changed: + module.exit_json(msg="file already exists but file attributes changed", dest=dest, url=url, changed=changed) + module.exit_json(msg="file already exists", dest=dest, url=url, changed=changed) # If the file already exists, prepare the last modified time for the # request. diff --git a/test/integration/targets/get_url/tasks/main.yml b/test/integration/targets/get_url/tasks/main.yml index d67eea69843..0c3df2fbaf6 100644 --- a/test/integration/targets/get_url/tasks/main.yml +++ b/test/integration/targets/get_url/tasks/main.yml @@ -241,7 +241,7 @@ # https://github.com/ansible/ansible/issues/29614 - name: Change mode on an already downloaded file and specify checksum get_url: - url: 'https://{{ httpbin_host }}/' + url: 'https://{{ httpbin_host }}/get' dest: '{{ output_dir }}/test' checksum: 'sha256:7036ede810fad2b5d2e7547ec703cae8da61edbba43c23f9d7203a0239b765c4.' mode: '0775' @@ -257,6 +257,17 @@ - result is changed - "stat_result.stat.mode == '0775'" +- name: Get a file that already exists + get_url: + url: 'https://{{ httpbin_host }}/get' + dest: '{{ output_dir }}/test' + register: result + +- name: Assert that we didn't re-download unnecessarily + assert: + that: + - result is not changed + # https://github.com/ansible/ansible/issues/27617 - name: set role facts