From b4a154267060bacd6ece3a58df642207d5ebe950 Mon Sep 17 00:00:00 2001 From: Mark Mielke Date: Sat, 21 Jan 2017 13:30:18 -0500 Subject: [PATCH] Reduce the system calls performed by the "file" module when using "state: link", and particularly when using "force: yes". Symbolic link resolution can be expensive. In our case, the symbolic links are legacy links to automounts, and the "file" task was causing all of the legacy links to be traversed and mounted on every host every time the task executed, even when the links were correct and there was nothing to do. This change avoids the system calls that perform the symbolic link resolution by taking advantage of the short circuit behaviur of the boolean "and" operator. The code behaviour is unchanged except that it no longer performs unnecessary system calls. As it turns out, this change is not sufficient to fully solve the symbolic link resolution problem, as the "file" module still performs a stat() at the end of execution to provide the caller with information about the file. However, this change is very simple, it will eliminate unnecessary system calls in a number of use cases, and it gets the "file" module closer to the desired end result. --- lib/ansible/modules/files/file.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ansible/modules/files/file.py b/lib/ansible/modules/files/file.py index ef98f036e8b..ac7790543c6 100644 --- a/lib/ansible/modules/files/file.py +++ b/lib/ansible/modules/files/file.py @@ -246,7 +246,7 @@ def main(): module.fail_json(msg='src and dest are required for creating links') # original_basename is used by other modules that depend on file. - if os.path.isdir(b_path) and state not in ("link", "absent"): + if state not in ("link", "absent") and os.path.isdir(b_path): basename = None if params['original_basename']: basename = params['original_basename'] @@ -362,7 +362,7 @@ def main(): elif state in ('link', 'hard'): - if os.path.isdir(b_path) and not os.path.islink(b_path): + if not os.path.islink(b_path) and os.path.isdir(b_path): relpath = path else: b_relpath = os.path.dirname(b_path) @@ -370,7 +370,7 @@ def main(): absrc = os.path.join(relpath, src) b_absrc = to_bytes(absrc, errors='surrogate_or_strict') - if not os.path.exists(b_absrc) and not force: + if not force and not os.path.exists(b_absrc): module.fail_json(path=path, src=src, msg='src file does not exist, use "force=yes" if you really want to create the link: %s' % absrc) if state == 'hard':