From 457f21a3362e823e36aa4dc7def5e1b9498841b6 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Fri, 6 Mar 2020 14:20:32 +0100 Subject: [PATCH] objectstore: add HostTree class to access host fs Simple new object that should expose the root file system with the same API as `objectstore.Object` but as read-only. This means that the `read` call works exactly as for `Object` but `write` raises an exception. Add tests to specifically check the read-only properties. --- osbuild/objectstore.py | 27 +++++++++++++++++++++++++++ test/test_objectstore.py | 15 +++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/osbuild/objectstore.py b/osbuild/objectstore.py index 5f71da58..67f8c0f6 100644 --- a/osbuild/objectstore.py +++ b/osbuild/objectstore.py @@ -203,6 +203,33 @@ class Object: return exc_type is None +class HostTree: + """Read-only access to the host file system + + An object that provides the same interface as + `objectstore.Object` that can be used to read + the host file-system. + """ + def __init__(self, store): + self.store = store + + @staticmethod + def write(): + raise ValueError("Cannot write to host") + + @contextlib.contextmanager + def read(self): + with self.store.tempdir() as tmp: + mount("/", tmp) + try: + yield tmp + finally: + umount(tmp) + + def cleanup(self): + pass # noop for the host + + class ObjectStore: def __init__(self, store): self.store = store diff --git a/test/test_objectstore.py b/test/test_objectstore.py index 325f796b..55568ea2 100644 --- a/test/test_objectstore.py +++ b/test/test_objectstore.py @@ -263,6 +263,21 @@ class TestObjectStore(unittest.TestCase): assert os.path.exists(f"{object_store.refs}/b/A") assert os.path.exists(f"{object_store.refs}/b/B") + def test_host_tree(self): + object_store = objectstore.ObjectStore(self.store) + host = objectstore.HostTree(object_store) + + # check we cannot call `write` + with self.assertRaises(ValueError): + with host.write() as _: + pass + + # check we actually cannot write to the path + with host.read() as path: + p = Path(f"{path}/osbuild-test-file") + with self.assertRaises(OSError): + p.touch() + if __name__ == "__main__": unittest.main()