This commit extends the method get_repo_name to also handle
squashed repos. This is done by mounting the squash file to
a temporary directory and then extracting the repository from
that directory with the already existing code.

This is motivated by wanting to mount each repo
to e.g. /var/db/repos/<repo-name> in a later commit.
For squashed repos, we don't know <repo-name> without
mounting the repo first. For this reason, it is mounted to
a temporary directory first to extract <repo-name>.

Signed-off-by: Felix Bier <felix.b...@rohde-schwarz.com>
---
 catalyst/support.py | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/catalyst/support.py b/catalyst/support.py
index fc50fa34..14d5a866 100644
--- a/catalyst/support.py
+++ b/catalyst/support.py
@@ -10,10 +10,12 @@ from subprocess import Popen
 import libmount
 
 from portage.repository.config import RepoConfig
+from tempfile import TemporaryDirectory
 
 from snakeoil.bash import read_bash_dict
 
 from catalyst import log
+from catalyst.context import namespace
 
 BASH_BINARY = "/bin/bash"
 
@@ -148,7 +150,7 @@ def read_makeconf(mymakeconffile):
         return makeconf
 
 
-def get_repo_name(repo_path):
+def get_repo_name_from_dir(repo_path):
     """ Get the name of the repo at the given repo_path.
 
          References:
@@ -164,6 +166,38 @@ def get_repo_name(repo_path):
     return repo_config.name
 
 
+def get_repo_name_from_squash(repo_squash_path):
+    """ Get the name of the repo at the given repo_squash_path.
+        To obtain the name, the squash file is mounted to a temporary 
directory.
+    """
+
+    repo_name = None
+
+    # Mount squash file to temp directory in separate mount namespace
+    with TemporaryDirectory() as temp, namespace(mount=True):
+        try:
+            source = str(repo_squash_path)
+            target = str(temp)
+            fstype = 'squashfs'
+            options = 'ro,loop'
+            cxt = libmount.Context(source=source, target=target,
+                                   fstype=fstype, options=options)
+            cxt.mount()
+            repo_name = get_repo_name_from_dir(target)
+
+        except Exception as e:
+            raise CatalystError(f"Couldn't mount: {source}, {e}")
+
+    return repo_name
+
+
+def get_repo_name(repo_path):
+    if not Path(repo_path).is_dir():
+        return get_repo_name_from_squash(repo_path)
+
+    return get_repo_name_from_dir(repo_path)
+
+
 def ismount(path):
     """Like os.path.ismount, but also support bind mounts"""
     path = Path(path)
-- 
2.30.0


Reply via email to