diff options
author | Brian Coca <bcoca@users.noreply.github.com> | 2021-04-05 10:16:45 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-05 09:16:45 -0500 |
commit | 1995b1b6e0a4f1812ade88317786da5ee2926a24 (patch) | |
tree | c4cee60bd975429507b8957fc964515bbecb4f1f | |
parent | 7683dfb7278afa24ee0d6d53968110b8bd467641 (diff) | |
download | ansible-1995b1b6e0a4f1812ade88317786da5ee2926a24.tar.gz |
find - set proper default based on use_regex (#73961) (#73965)
When using "use_regex: yes" and setting an excludes: without
specifying a pattern: the existing code passes the file-glob '*' to
the regex matcher. This results in an internal invalid-regex
exception being thrown.
This maintains the old semantics of a default match-all for pattern:
but switches the default to '.*' when use_regex is specified.
The code made sense as-is before excludes: was added (2.5). In that
case, it made no sense to set use_regex but *not* set a pattern.
However, with excludes: it now makes sense to only want to exclude a
given regex but not specify a specific matching pattern.
Closes: #50067
* moved change to new location
added changelog
* Update lib/ansible/modules/find.py
Co-authored-by: Ian Wienand <iwienand@redhat.com>
(cherry picked from commit 089d0a0508a470799d099d95fc371e66756a00b3)
* Fix up bad rebase, nuke duplicate "elements:" lines
Signed-off-by: Rick Elrod <rick@elrod.me>
Co-authored-by: Rick Elrod <rick@elrod.me>
Co-authored-by: Brian Coca <bcoca@users.noreply.github.com>
Co-authored-by: Sam Doran <sdoran@redhat.com>
-rw-r--r-- | changelogs/fragments/fix_find_default.yml | 2 | ||||
-rw-r--r-- | lib/ansible/modules/find.py | 21 | ||||
-rw-r--r-- | test/integration/targets/find/tasks/main.yml | 22 |
3 files changed, 40 insertions, 5 deletions
diff --git a/changelogs/fragments/fix_find_default.yml b/changelogs/fragments/fix_find_default.yml new file mode 100644 index 0000000000..b49a88da82 --- /dev/null +++ b/changelogs/fragments/fix_find_default.yml @@ -0,0 +1,2 @@ +bugfixes: + - find - fix default pattern when use_regex is true (https://github.com/ansible/ansible/issues/50067). diff --git a/lib/ansible/modules/find.py b/lib/ansible/modules/find.py index b831e86eec..1aebaf9be0 100644 --- a/lib/ansible/modules/find.py +++ b/lib/ansible/modules/find.py @@ -29,7 +29,7 @@ options: first letter of any of those words (e.g., "1w"). type: str patterns: - default: '*' + default: [] description: - One or more (shell or regex) patterns, which type is controlled by C(use_regex) option. - The patterns restrict the list of files to be returned to those whose basenames match at @@ -41,18 +41,19 @@ options: - This parameter expects a list, which can be either comma separated or YAML. If any of the patterns contain a comma, make sure to put them in a list to avoid splitting the patterns in undesirable ways. + - Defaults to '*' when C(use_regex=False), or '.*' when C(use_regex=True). type: list - aliases: [ pattern ] elements: str + aliases: [ pattern ] excludes: description: - One or more (shell or regex) patterns, which type is controlled by C(use_regex) option. - Items whose basenames match an C(excludes) pattern are culled from C(patterns) matches. Multiple patterns can be specified using a list. type: list + elements: str aliases: [ exclude ] version_added: "2.5" - elements: str contains: description: - A regular expression or pattern which should be matched against the file content. @@ -62,8 +63,8 @@ options: - List of paths of directories to search. All paths must be fully qualified. type: list required: true - aliases: [ name, path ] elements: str + aliases: [ name, path ] file_type: description: - Type of file to select. @@ -360,7 +361,7 @@ def main(): module = AnsibleModule( argument_spec=dict( paths=dict(type='list', required=True, aliases=['name', 'path'], elements='str'), - patterns=dict(type='list', default=['*'], aliases=['pattern'], elements='str'), + patterns=dict(type='list', default=[], aliases=['pattern'], elements='str'), excludes=dict(type='list', aliases=['exclude'], elements='str'), contains=dict(type='str'), file_type=dict(type='str', default="file", choices=['any', 'directory', 'file', 'link']), @@ -379,6 +380,16 @@ def main(): params = module.params + # Set the default match pattern to either a match-all glob or + # regex depending on use_regex being set. This makes sure if you + # set excludes: without a pattern pfilter gets something it can + # handle. + if not params['patterns']: + if params['use_regex']: + params['patterns'] = ['.*'] + else: + params['patterns'] = ['*'] + filelist = [] if params['age'] is None: diff --git a/test/integration/targets/find/tasks/main.yml b/test/integration/targets/find/tasks/main.yml index 6879404d88..d38daf44aa 100644 --- a/test/integration/targets/find/tasks/main.yml +++ b/test/integration/targets/find/tasks/main.yml @@ -139,3 +139,25 @@ # dir contents are considered until the depth exceeds the requested depth # there are 6 files/directories in the requested depth and 4 that exceed it by 1 - files_with_depth.examined == 10 + +- name: exclude with regex + find: + paths: "{{ output_dir_test }}" + recurse: yes + use_regex: true + exclude: .*\.ogg + register: find_test3 +# Note that currently sane ways of doing this with map() or +# selectattr() aren't available in centos6 era jinja2 ... +- set_fact: + find_test3_list: >- + [ {% for f in find_test3.files %} + {{ f.path }} + {% if not loop.last %},{% endif %} + {% endfor %} + ] +- debug: var=find_test3_list +- name: assert we skipped the ogg file + assert: + that: + - '"{{ output_dir_test }}/e/f/g/h/8.ogg" not in find_test3_list' |