objectstore: manually cleanup tree dir for Object
The tree, which is created by stages and assemblers, might contain immutable files, which for Python 3 currently (version 3.8) leads to errors when the tempfile.TemporaryDirectory is being cleaned up. Therefore, manually cleanup the tree directory, if it exists, via shutil.rmtree with a custom onerror handler that also removes the immutable bit on permission errors.
This commit is contained in:
parent
509d2ee895
commit
04aa5e0aeb
1 changed files with 36 additions and 0 deletions
|
|
@ -3,6 +3,7 @@ import contextlib
|
||||||
import errno
|
import errno
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
import weakref
|
import weakref
|
||||||
|
|
@ -52,6 +53,35 @@ def umount(target, lazy=True):
|
||||||
subprocess.run(["umount"] + args + [target], check=True)
|
subprocess.run(["umount"] + args + [target], check=True)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_tree(path):
|
||||||
|
def fixperms(p):
|
||||||
|
subprocess.run(["chattr", "-i", p],
|
||||||
|
check=False)
|
||||||
|
os.chmod(p, 0o777)
|
||||||
|
|
||||||
|
def unlink(p):
|
||||||
|
try:
|
||||||
|
os.unlink(p)
|
||||||
|
except IsADirectoryError:
|
||||||
|
remove_tree(p)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_error(_fn, p, exc_info):
|
||||||
|
e = exc_info[0]
|
||||||
|
if issubclass(e, FileNotFoundError):
|
||||||
|
pass
|
||||||
|
elif issubclass(e, PermissionError):
|
||||||
|
if p != path:
|
||||||
|
fixperms(os.path.dirname(p))
|
||||||
|
fixperms(p)
|
||||||
|
unlink(p)
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
shutil.rmtree(path, onerror=on_error)
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-instance-attributes
|
# pylint: disable=too-many-instance-attributes
|
||||||
class Object:
|
class Object:
|
||||||
def __init__(self, store: "ObjectStore"):
|
def __init__(self, store: "ObjectStore"):
|
||||||
|
|
@ -158,6 +188,12 @@ class Object:
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
self._check_readers()
|
self._check_readers()
|
||||||
self._check_writer()
|
self._check_writer()
|
||||||
|
if self._tree:
|
||||||
|
# manually remove the tree, it might contain
|
||||||
|
# files with immutable flag set, which will
|
||||||
|
# throw off standard Python 3 tempdir cleanup
|
||||||
|
remove_tree(self._tree)
|
||||||
|
self._tree = None
|
||||||
if self._workdir:
|
if self._workdir:
|
||||||
self._workdir.cleanup()
|
self._workdir.cleanup()
|
||||||
self._workdir = None
|
self._workdir = None
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue