objectstore: object manages its work dir

When a new object is being created, a corresponding temporary
directory is created within the file system tree of the object
store, which shall be called the "work dir". Within that dir a
well-known directory ('tree') is created that then is the root
of the filesystem tree[1] that clients use to store the tree
or the resulting image in.
Previously, the work dir was managed, i.e. created and cleaned
up (via a context manager) by the ObjectStore. Now the Object
itself manages the tree and thus the lifetime of the work dir
is more directly integrated and controlled by it. As a result
the Object itself is now a context manager. On exit of the
context the work dir is cleaned up.

[1] For the assembler this is the output directory that will
    contain the final image.
This commit is contained in:
Christian Kellner 2020-02-17 16:54:29 +01:00 committed by Tom Gundersen
parent 399606528c
commit 6d14dee9a2

View file

@ -28,10 +28,11 @@ def suppress_oserror(*errnos):
class Object:
def __init__(self, store: "ObjectStore", path: str):
def __init__(self, store: "ObjectStore"):
self._workdir = None
self._tree = None
self.store = store
os.makedirs(path, mode=0o755, exist_ok=True)
self.path = path
self.reset()
def init(self, source: str) -> None:
"""Initialize the object with source content"""
@ -39,6 +40,10 @@ class Object:
f"{source}/.", self.path],
check=True)
@property
def path(self) -> str:
return self._tree
@property
def treesum(self) -> str:
"""Calculate the treesum of the object"""
@ -65,7 +70,25 @@ class Object:
"""
with suppress_oserror(errno.ENOTEMPTY, errno.EEXIST):
os.rename(self.path, destination)
self.path = destination
self._tree = destination
def reset(self):
self.cleanup()
self._workdir = self.store.tempdir(suffix="object")
self._tree = os.path.join(self._workdir.name, "tree")
os.makedirs(self._tree, mode=0o755, exist_ok=True)
def cleanup(self):
if self._workdir:
self._workdir.cleanup()
self._workdir = None
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.cleanup()
return exc_type is None
class ObjectStore:
@ -118,10 +141,9 @@ class ObjectStore:
store if the context completes without raising an exception.
"""
with self.tempdir() as tmp:
with Object(self) as obj:
# the object that is yielded will be added to the content store
# on success as object_id
obj = Object(self, f"{tmp}/tree")
if base_id:
# the base, the working tree and the output dir are all
@ -150,8 +172,7 @@ class ObjectStore:
# Make a new temporary directory and Object; initialize
# the latter with the contents of `object_path` and commit
# it to the store
with self.tempdir() as tmp:
obj = Object(self, f"{tmp}/tree")
with Object(self) as obj:
obj.init(object_path)
return self.commit(obj, object_id)