summaryrefslogtreecommitdiffstats
path: root/tools/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/__init__.py')
-rw-r--r--tools/__init__.py73
1 files changed, 73 insertions, 0 deletions
diff --git a/tools/__init__.py b/tools/__init__.py
new file mode 100644
index 0000000..e25ef6f
--- /dev/null
+++ b/tools/__init__.py
@@ -0,0 +1,73 @@
+import logging
+import os
+
+from functools import wraps
+from subprocess import run
+
+__all__ = ["unmount", "rmdir"]
+
+L = logging.getLogger(__name__)
+
+
+def log(func):
+ """Simple decorator for logging function calls."""
+ @wraps(func)
+ def _log(*args, **kwargs):
+ args_repr = [repr(a) for a in args]
+ kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
+ params = ", ".join(args_repr + kwargs_repr)
+ file_name = os.path.basename(func.__code__.co_filename)
+ file_name = os.path.splitext(file_name)[0]
+ func_name = func.__name__ if file_name == "__init__" \
+ else f"{file_name}.{func.__name__}"
+ L.debug("%s called with %s", func_name, params)
+ try:
+ result = func(*args, **kwargs)
+ L.debug("%s returned %s", func_name, result)
+ return result
+ except Exception as e:
+ L.error("%s raised %r", func_name, e)
+ raise e
+ return _log
+
+
+@log
+def unmount(path):
+ """Unmount a FUSE filesystem using fusermount.
+
+ See also:
+ https://manpages.debian.org/bullseye/fuse/fusermount.1.en.html
+
+ Args:
+ path (str): Path to the mounted FUSE filesystem.
+
+ Returns:
+ True if the command was successful, False otherwise.
+ """
+ cmd = ["fusermount", "-u", path]
+ try:
+ p = run(cmd, capture_output=True, check=False, text=True)
+ except Exception as e:
+ L.error("failed to execute command %s: %r", cmd, e)
+ return False
+
+ return not p.returncode
+
+
+@log
+def rmdir(path):
+ """Remove a directory.
+
+ Args:
+ path (str): Path to directory.
+
+ Returns:
+ True if the command was successful, False otherwise.
+ """
+ try:
+ os.rmdir(path)
+ except OSError as e:
+ L.error("failed to remove directory %s: %r", path, e)
+ return False
+
+ return True