diff options
author | Sam Doran <sdoran@redhat.com> | 2021-07-12 11:33:08 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-12 10:33:08 -0500 |
commit | 420527bebfe535ecb646b5f40e347b767560a6ce (patch) | |
tree | 710e45536f3a0a04a24c75ec84b60d7d42cde699 | |
parent | 1f4d1dfa0b94b8dd45762726c30c2b204b3416cd (diff) | |
download | ansible-420527bebfe535ecb646b5f40e347b767560a6ce.tar.gz |
[stable-2.11] module_common - handle cache directory creation collision (#75106) (#75132)
* module_common - handle cache directory creation collision
Occasionally multiple workers can try to create the cache directory if it exists. Catch the exception
and handle it.
* Just re-raise if it doesn't exist rather than trying again
* Use exists_ok rather than handling an exception
* Remove unused import and unused variable
* Go back to try/except but with OSError
Since we do not have split controller remote, this needs to be able to run in Python 2 in order
to be merged currently.
(cherry picked from commit 16a74b798c)
Co-authored-by: Sam Doran <sdoran@redhat.com>
-rw-r--r-- | changelogs/fragments/concurrency-cache-dir-collision.yml | 2 | ||||
-rw-r--r-- | lib/ansible/executor/module_common.py | 15 |
2 files changed, 12 insertions, 5 deletions
diff --git a/changelogs/fragments/concurrency-cache-dir-collision.yml b/changelogs/fragments/concurrency-cache-dir-collision.yml new file mode 100644 index 0000000000..fbf62699dc --- /dev/null +++ b/changelogs/fragments/concurrency-cache-dir-collision.yml @@ -0,0 +1,2 @@ +bugfixes: + - module_common - handle exception when multiple workers try to create the cache directory diff --git a/lib/ansible/executor/module_common.py b/lib/ansible/executor/module_common.py index ffabb7445a..ce114ce488 100644 --- a/lib/ansible/executor/module_common.py +++ b/lib/ansible/executor/module_common.py @@ -34,7 +34,7 @@ from io import BytesIO from ansible.release import __version__, __author__ from ansible import constants as C -from ansible.errors import AnsibleError, AnsiblePluginRemovedError +from ansible.errors import AnsibleError from ansible.executor.interpreter_discovery import InterpreterDiscoveryRequiredError from ansible.executor.powershell import module_manifest as ps_manifest from ansible.module_utils.common.json import AnsibleJSONEncoder @@ -1115,7 +1115,6 @@ def _find_module_utils(module_name, b_module_data, module_path, module_args, tas return b_module_data, module_style, shebang output = BytesIO() - py_module_names = set() try: remote_module_fqn = _get_ansible_module_fqn(module_path) @@ -1186,9 +1185,15 @@ def _find_module_utils(module_name, b_module_data, module_path, module_args, tas # so that no one looking for the file reads a partially # written file) if not os.path.exists(lookup_path): - # Note -- if we have a global function to setup, that would - # be a better place to run this - os.makedirs(lookup_path) + try: + # Note -- if we have a global function to setup, that would + # be a better place to run this + os.makedirs(lookup_path) + except OSError: + # Multiple processes tried to create the directory. If it still does not + # exist, raise the original exception. + if not os.path.exists(lookup_path): + raise display.debug('ANSIBALLZ: Writing module') with open(cached_module_filename + '-part', 'wb') as f: f.write(zipdata) |