From 6d14dee9a28ffda9cad89daf0713d021c3303f41 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Mon, 17 Feb 2020 16:54:29 +0100 Subject: [PATCH] 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. --- osbuild/objectstore.py | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/osbuild/objectstore.py b/osbuild/objectstore.py index e8fda862..360578d3 100644 --- a/osbuild/objectstore.py +++ b/osbuild/objectstore.py @@ -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)