diff --git a/CHANGES.rst b/CHANGES.rst index 88b983e4bf..717ad2aded 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -37,6 +37,12 @@ Compute Storage ~~~~~~~ +- [Local] Remove the IPC lock file once ``LockLocalStorage`` releases the lock. + Previously ``fasteners`` left the file behind, so one file accumulated in the + temporary directory for every distinct path which was locked. + (GITHUB-1975) + [Sanjay Santhanam - @Sanjays2402] + - [Azure Blobs] Fix ``chunk_size`` argument being ignored by ``download_object_as_stream`` and ``download_object_range_as_stream``. The requested chunk size is now forwarded to the underlying iterator instead of diff --git a/libcloud/storage/drivers/local.py b/libcloud/storage/drivers/local.py index f47d7c0649..9f15ce4dc4 100644 --- a/libcloud/storage/drivers/local.py +++ b/libcloud/storage/drivers/local.py @@ -117,6 +117,14 @@ def __exit__(self, type, value, traceback): if self.ipc_lock.exists(): self.ipc_lock.release() + # NOTE: fasteners doesn't remove the lock file it creates, so + # without this the file accumulates in the temporary directory + # for every distinct path which is ever locked. + try: + os.remove(self.ipc_lock_path) + except OSError: + pass + if value is not None: raise value diff --git a/libcloud/test/storage/test_local.py b/libcloud/test/storage/test_local.py index 7d7f271405..0ff5f42836 100644 --- a/libcloud/test/storage/test_local.py +++ b/libcloud/test/storage/test_local.py @@ -139,6 +139,18 @@ def test_lock_local_storage(self): self.assertEqual(bool(success_1.value), True, "Check didn't pass") self.assertEqual(bool(success_2.value), True, "Second check didn't pass") + @unittest.skipIf(platform.system().lower() == "windows", "Unsupported on Windows") + def test_lock_local_storage_removes_lock_file(self): + # The IPC lock file must not be left behind once the lock is released, + # otherwise it accumulates in the temporary directory for every path + # which is ever locked. + lock = LockLocalStorage("/tmp/lock-file-cleanup") + + with lock: + self.assertTrue(os.path.exists(lock.ipc_lock_path)) + + self.assertFalse(os.path.exists(lock.ipc_lock_path)) + def test_list_containers_empty(self): containers = self.driver.list_containers() self.assertEqual(len(containers), 0)