From e30da5173160887ad88d8f066fb2d4f783c7fa10 Mon Sep 17 00:00:00 2001 From: Ben Buchwald Date: Thu, 11 Sep 2025 19:09:59 -0400 Subject: [PATCH] Fix jsonfile cache on WSL (#85816) On WSL, `os.rename` can't correctly move a file while a handle to that file is still open. It remains half-moved where neither the source or destination seem to exist (according to `os.path.exists`). However the move seems to complete correctly when the open handle is closed. In `BaseFileCacheModule`, when writing a cache file, a temporary file is created with `mkstemp` that returns an open file descriptor and a filename. Once the cache is written to that file, it is renamed to the correct file name with `os.rename` and then its permissions set with `os.chmod`. On WSL the `os.chmod` fails because it doesn't think the file exists yet because the file descriptor returned by `mkstemp` is still open. This PR fixes this by closing that file descriptor before renaming. Co-authored-by: Abhijeet Kasurde --- changelogs/fragments/85816-wsl-cache-files.yml | 2 ++ lib/ansible/plugins/cache/__init__.py | 1 + 2 files changed, 3 insertions(+) create mode 100644 changelogs/fragments/85816-wsl-cache-files.yml diff --git a/changelogs/fragments/85816-wsl-cache-files.yml b/changelogs/fragments/85816-wsl-cache-files.yml new file mode 100644 index 00000000000..0ecf10abc6f --- /dev/null +++ b/changelogs/fragments/85816-wsl-cache-files.yml @@ -0,0 +1,2 @@ +bugfixes: + - cache plugins - close temp cache file before moving it to fix error on WSL. (https://github.com/ansible/ansible/pull/85816) diff --git a/lib/ansible/plugins/cache/__init__.py b/lib/ansible/plugins/cache/__init__.py index 4ec276bca67..ec94fb1e12e 100644 --- a/lib/ansible/plugins/cache/__init__.py +++ b/lib/ansible/plugins/cache/__init__.py @@ -162,6 +162,7 @@ class BaseFileCacheModule(BaseCacheModule): except OSError as ex: display.error_as_warning(f"Error in {self.plugin_name!r} cache plugin while trying to write to {tmpfile_path!r}.", exception=ex) try: + os.close(tmpfile_handle) # os.rename fails if handle is still open in WSL os.rename(tmpfile_path, cachefile) os.chmod(cachefile, mode=S_IRWU_RG_RO) except OSError as ex: