diff --git a/changelogs/fragments/wait_for_mmap.yml b/changelogs/fragments/wait_for_mmap.yml new file mode 100644 index 00000000000..c5ee952fce5 --- /dev/null +++ b/changelogs/fragments/wait_for_mmap.yml @@ -0,0 +1,2 @@ +bugfixes: + - wait_for should not handle 'non mmapable files' again. diff --git a/lib/ansible/modules/wait_for.py b/lib/ansible/modules/wait_for.py index 907c78e9d05..2230e6ee75b 100644 --- a/lib/ansible/modules/wait_for.py +++ b/lib/ansible/modules/wait_for.py @@ -237,7 +237,7 @@ import traceback from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.common.sys_info import get_platform_subclass -from ansible.module_utils.common.text.converters import to_bytes +from ansible.module_utils.common.text.converters import to_bytes, to_native from ansible.module_utils.compat.datetime import utcnow @@ -584,17 +584,30 @@ def main(): if not b_compiled_search_re: # nope, succeed! break + try: with open(b_path, 'rb') as f: - with contextlib.closing(mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)) as mm: - search = b_compiled_search_re.search(mm) + try: + with contextlib.closing(mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)) as mm: + search = b_compiled_search_re.search(mm) + if search: + if search.groupdict(): + match_groupdict = search.groupdict() + if search.groups(): + match_groups = search.groups() + break + except (ValueError, OSError) as e: + module.debug('wait_for failed to use mmap on "%s": %s. Falling back to file read().' % (path, to_native(e))) + # cannot mmap this file, try normal read + search = re.search(b_compiled_search_re, f.read()) if search: if search.groupdict(): match_groupdict = search.groupdict() if search.groups(): match_groups = search.groups() - break + except Exception as e: + module.warn('wait_for failed on "%s", unexpected exception(%s): %s.).' % (path, to_native(e.__class__), to_native(e))) except IOError: pass elif port: diff --git a/test/integration/targets/wait_for/tasks/main.yml b/test/integration/targets/wait_for/tasks/main.yml index f71ddbda6b0..8fadbf38a03 100644 --- a/test/integration/targets/wait_for/tasks/main.yml +++ b/test/integration/targets/wait_for/tasks/main.yml @@ -91,7 +91,7 @@ wait_for: path: "{{remote_tmp_dir}}/wait_for_keyword" search_regex: completed (?P\w+) ([0-9]+) - timeout: 5 + timeout: 25 register: waitfor - name: verify test wait for keyword in file with match groups @@ -114,6 +114,13 @@ path: "{{remote_tmp_dir}}/utf16.txt" search_regex: completed +- name: test non mmapable file + wait_for: + path: "/sys/class/net/lo/carrier" + search_regex: "1" + timeout: 30 + when: ansible_os_family not in ['FreeBSD', 'Darwin'] + - name: test wait for port timeout wait_for: port: 12121