Repository: ansible/ansible
Pull request: wait_for module - document self match avoidance
When using static string to search system log, avoid matching self execution logged by Ansible by default.


fixes #85244

<!--- Describe the change below, including rationale -->

<!--- Add "Fixes #1234" if there is a corresponding issue -->

##### ISSUE TYPE

- Docs Pull Request


Problem statement:
wait_for wrongly detects pattern due to self-logging
### Summary

When using the `wait_for` module with the `search_regex` option to monitor log files (e.g., `/var/log/messages`), the module may falsely detect the pattern as matched due to Ansible itself writing the `search_regex` string into the same log file. This causes `wait_for` to succeed before the actual event occurs.

### Example

```
- name: ---- test waitfor module ----
  wait_for:
    path: /var/log/messages
    search_regex: 'Started NTP client/server'
  tags: waitforntp

- name: ---- show waitfor module message ----
  debug:
    msg: 'Chrony Server is Running now'
  tags: waitforntp
```

### Issue Type

Bug Report

### Component Name

dnf

### Ansible Version

```console
$ ansible --version
ansible [core 2.15.13]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/devops/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
  ansible collection location = /home/devops/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.21 (main, Dec  5 2024, 00:00:00) [GCC 11.5.0 20240719 (Red Hat 11.5.0-2)] (/usr/bin/python3)
  jinja version = 3.1.5
  libyaml = True
```

### Configuration

```console
# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ ansible-config dump --only-changed -t all
```

### OS / Environment

Rocky Linux  9.5

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)

```


### Expected Results

When running the playbook with `wait_for` and `search_regex` to monitor a log file for the phrase indicating that the 'Started NTP client/server'` , I expect the module to:

- Wait until the actual log entry confirming that `chronyd` is running appears in the latest lines of the log file.
- Only then succeed and report that the time server is up.

In other words, the module should not falsely succeed before the real event occurs, and it should ignore any log entries generated by Ansible itself that contain the search pattern.


### Actual Results

```console
When running the playbook, the `wait_for` module immediately reports success, indicating that the time server is up, even though the `chronyd` service has not actually started yet.

This happens because Ansible itself writes a log entry containing the search pattern (`search_regex`) into the monitored log file (e.g., `/var/log/messages`). As a result, `wait_for` falsely detects this log entry as the real event, causing premature success.
```

### Code of Conduct

- [x] I agree to follow the Ansible Code of Conduct

Hints from issue discussion:
Files identified in the description:

* [`lib/ansible/modules/dnf.py`](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/dnf.py)
* [`lib/ansible/plugins/action/dnf.py`](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/action/dnf.py)

If these files are incorrect, please update the `component name` section of the description or use the [component](https://github.com/ansible/ansibotmini#commands) bot command.

<!--- boilerplate: components_banner --->

@seighalani `ansible-core` 2.15 is not supported and no longer receives bug fixes. Please test against one of [the supported versions](https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix) of `ansible-core`, preferably the most recent one, to see whether the bug has been fixed.

[click here for bot help](https://github.com/ansible/ansibotmini#ansibotmini)
<!--- boilerplate: unsupported_version --->

This is not a bug. You told Ansible to wait until the file content matched the regex, and it did so.
Replacing `search_regex: 'Started NTP client/server'` by `search_regex: 'Started NTP [c]lient/server'` should fix your problem, since then the regex won't match itself anymore :)
i'm 60/40 on this being a bug, I do lean to excluding your own output when grepping ... `ps -eaf |grep stuff |grep -v grep` .

At the very least this is worth documenting and having an example for the workaround above.

Commit message: wait_for module - document self match avoidance

When using static string to search system log, avoid matching self execution
logged by Ansible by default.

Patch to review:
diff --git a/lib/ansible/modules/wait_for.py b/lib/ansible/modules/wait_for.py
index 49bc7cde63c9c3..141a60f199f3ff 100644
--- a/lib/ansible/modules/wait_for.py
+++ b/lib/ansible/modules/wait_for.py
@@ -76,6 +76,7 @@
     description:
       - Can be used to match a string in either a file or a socket connection.
       - Defaults to a multiline regex.
+      - When inspecting a system log file and a static string, remember that Ansible by default logs it's own actions there, see notes and examples.
     type: str
     version_added: "1.4"
   exclude_hosts:
@@ -105,13 +106,12 @@
     platform:
         platforms: posix
 notes:
-  - The ability to use search_regex with a port connection was added in Ansible 1.7.
-  - Prior to Ansible 2.4, testing for the absence of a directory or UNIX socket did not work correctly.
-  - Prior to Ansible 2.4, testing for the presence of a file did not work correctly if the remote user did not have read access to that file.
   - Under some circumstances when using mandatory access control, a path may always be treated as being absent even if it exists, but
     can't be modified or created by the remote user either.
   - When waiting for a path, symbolic links will be followed.  Many other modules that manipulate files do not follow symbolic links,
     so operations on the path using other modules may not work exactly as expected.
+  - When using a static string for search on a system log, take into account Ansible modules log their own activity there too, add a regex construct
+    to the string to avoid self matching.  For example, to match 'this thing', you can write 'this t[h]ing'.
 seealso:
 - module: ansible.builtin.wait_for_connection
 - module: ansible.windows.win_wait_for
@@ -156,6 +156,11 @@
     path: /tmp/foo
     search_regex: completed
 
+- name: Wait until the string "tomcat up" is in syslog, use regex character set to avoid self match
+  ansible.builtin.wait_for:
+    path: /var/log/syslog
+    search_regex: 'tomcat [u]p'
+
 - name: Wait until regex pattern matches in the file /tmp/foo and print the matched group
   ansible.builtin.wait_for:
     path: /tmp/foo


Code review comments:
diff_hunk: @@ -76,6 +76,7 @@
     description:
       - Can be used to match a string in either a file or a socket connection.
       - Defaults to a multiline regex.
+      - When inspecting a system log file and a static string, remember that Ansible by default logs it's own actions there, see notes and examples.
path: lib/ansible/modules/wait_for.py
text: @user1:
```suggestion
      - When inspecting a system log file and a static string, remember that Ansible by default logs its own actions there; see the notes and examples for information.
```

diff_hunk: @@ -105,13 +106,12 @@
     platform:
         platforms: posix
 notes:
-  - The ability to use search_regex with a port connection was added in Ansible 1.7.
-  - Prior to Ansible 2.4, testing for the absence of a directory or UNIX socket did not work correctly.
-  - Prior to Ansible 2.4, testing for the presence of a file did not work correctly if the remote user did not have read access to that file.
   - Under some circumstances when using mandatory access control, a path may always be treated as being absent even if it exists, but
     can't be modified or created by the remote user either.
   - When waiting for a path, symbolic links will be followed.  Many other modules that manipulate files do not follow symbolic links,
     so operations on the path using other modules may not work exactly as expected.
+  - When using a static string for search on a system log, take into account Ansible modules log their own activity there too, add a regex construct
+    to the string to avoid self matching.  For example, to match 'this thing', you can write 'this t[h]ing'.
path: lib/ansible/modules/wait_for.py
text: @user1:
```suggestion
  - When searching a static string within a system log file, it is important to account for potential self-matching against log entries generated by the Ansible modules. To prevent this, add a regular expression construct into the search string. For example, to match a literal string 'this thing', one could use a regular expression like 'this t[h]ing'.
```