From 8628c12f30693e520b6c7bcb816bbcbbbe0cd5bb Mon Sep 17 00:00:00 2001 From: Sloane Hertel <19572925+s-hertel@users.noreply.github.com> Date: Thu, 25 Feb 2021 14:32:49 -0500 Subject: [PATCH] find module - stop traversing directories with os.walk when depth is already exceeded (#73718) --- .../73718-find-dir-depth-traversal.yml | 2 + lib/ansible/modules/find.py | 2 + test/integration/targets/find/tasks/main.yml | 44 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 changelogs/fragments/73718-find-dir-depth-traversal.yml diff --git a/changelogs/fragments/73718-find-dir-depth-traversal.yml b/changelogs/fragments/73718-find-dir-depth-traversal.yml new file mode 100644 index 00000000000..daf479c9fd3 --- /dev/null +++ b/changelogs/fragments/73718-find-dir-depth-traversal.yml @@ -0,0 +1,2 @@ +bugfixes: + - find module - Stop traversing directories past the requested depth. (https://github.com/ansible/ansible/issues/73627) diff --git a/lib/ansible/modules/find.py b/lib/ansible/modules/find.py index 04efff23843..323d0223f26 100644 --- a/lib/ansible/modules/find.py +++ b/lib/ansible/modules/find.py @@ -436,6 +436,8 @@ def main(): wpath = npath.rstrip(os.path.sep) + os.path.sep depth = int(fsname.count(os.path.sep)) - int(wpath.count(os.path.sep)) + 1 if depth > params['depth']: + # Empty the list used by os.walk to avoid traversing deeper unnecessarily + del(dirs[:]) continue if os.path.basename(fsname).startswith('.') and not params['hidden']: continue diff --git a/test/integration/targets/find/tasks/main.yml b/test/integration/targets/find/tasks/main.yml index 82d5daab26d..2678c954127 100644 --- a/test/integration/targets/find/tasks/main.yml +++ b/test/integration/targets/find/tasks/main.yml @@ -71,6 +71,7 @@ - 'find_test0.msg is defined' - 'find_test0.matched == 8' - 'find_test0.files | length == 8' + - 'find_test0.examined == 16' - name: find the xml and img files find: @@ -207,3 +208,46 @@ that: - failed_path.files == [] - failed_path.msg.startswith("Skipped '{{mypath}}' path due to this access issue") + +- name: test number of examined directories/files + block: + - name: Get all files/directories in the path + find: + paths: "{{ output_dir_test }}" + recurse: yes + file_type: any + register: total_contents + + - assert: + that: + - total_contents.matched == 18 + - total_contents.examined == 18 + + - name: Get files and directories with depth + find: + paths: "{{ output_dir_test }}" + recurse: yes + file_type: any + depth: 2 + register: contents_with_depth + + - assert: + that: + - contents_with_depth.matched == 8 + # dir contents are considered until the depth exceeds the requested depth + # there are 8 files/directories in the requested depth and 4 that exceed it by 1 + - contents_with_depth.examined == 12 + + - name: Find files with depth + find: + paths: "{{ output_dir_test }}" + depth: 2 + recurse: yes + register: files_with_depth + + - assert: + that: + - files_with_depth.matched == 4 + # dir contents are considered until the depth exceeds the requested depth + # there are 8 files/directories in the requested depth and 4 that exceed it by 1 + - files_with_depth.examined == 12