commit:     e042cf37bcb4f4c4e7c1665f69faf971fa8177e8
Author:     Matt Turner <mattst88 <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 28 21:59:17 2020 +0000
Commit:     Matt Turner <mattst88 <AT> gentoo <DOT> org>
CommitDate: Thu Oct 29 14:24:15 2020 +0000
URL:        https://gitweb.gentoo.org/proj/catalyst.git/commit/?id=e042cf37

catalyst: Add and use namespace context manager

Signed-off-by: Matt Turner <mattst88 <AT> gentoo.org>

 catalyst/base/stagebase.py |  6 ++++--
 catalyst/context.py        | 33 +++++++++++++++++++++++++++++++++
 catalyst/main.py           | 17 +++++++----------
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/catalyst/base/stagebase.py b/catalyst/base/stagebase.py
index da133bf2..2bbbb987 100644
--- a/catalyst/base/stagebase.py
+++ b/catalyst/base/stagebase.py
@@ -14,6 +14,7 @@ from snakeoil.osutils import pjoin
 from DeComp.compress import CompressMap
 
 from catalyst import log
+from catalyst.context import namespace
 from catalyst.defaults import (confdefaults, MOUNT_DEFAULTS, PORT_LOGDIR_CLEAN)
 from catalyst.support import (CatalystError, file_locate, normpath,
                               cmd, read_makeconf, ismount, file_check,
@@ -1392,8 +1393,9 @@ class StageBase(TargetBase, ClearBase, GenBase):
         if not self.run_sequence(self.prepare_sequence):
             return False
 
-        if not self.run_sequence(self.build_sequence):
-            return False
+        with namespace(mount=True):
+            if not self.run_sequence(self.build_sequence):
+                return False
 
         if not self.run_sequence(self.finish_sequence):
             return False

diff --git a/catalyst/context.py b/catalyst/context.py
new file mode 100644
index 00000000..b53be56e
--- /dev/null
+++ b/catalyst/context.py
@@ -0,0 +1,33 @@
+
+import contextlib
+import os
+
+from snakeoil.process.namespaces import setns, simple_unshare
+
[email protected]
+def namespace(mount=False, uts=False, ipc=False, net=False, pid=False,
+              user=False, hostname=None):
+    namespaces = {
+        (mount, "mnt"):  None,
+        (uts,   "uts"):  None,
+        (ipc,   "ipc"):  None,
+        (net,   "net"):  None,
+        (pid,   "pid"):  None,
+        (user,  "user"): None,
+    }
+    process_id = os.getpid()
+
+    # Save fds of current namespaces
+    for ns in [ns for ns in namespaces if ns[0]]:
+        fp = open(f"/proc/{process_id}/ns/{ns[1]}")
+        namespaces[ns] = fp
+
+    simple_unshare(mount=mount, uts=uts, ipc=ipc, net=net, pid=pid, user=user,
+                   hostname=hostname)
+    try:
+        yield None
+    finally:
+        for ns in [ns for ns in namespaces if ns[0]]:
+            fp = namespaces[ns]
+            setns(fp.fileno(), 0)
+            fp.close()

diff --git a/catalyst/main.py b/catalyst/main.py
index 543895c6..93a4a0d3 100644
--- a/catalyst/main.py
+++ b/catalyst/main.py
@@ -7,14 +7,13 @@ import textwrap
 
 import toml
 
-from snakeoil.process import namespaces
-
 from DeComp.definitions import (COMPRESS_DEFINITIONS, DECOMPRESS_DEFINITIONS,
                                 CONTENTS_DEFINITIONS)
 from DeComp.contents import ContentsMap
 
 from catalyst import log
 import catalyst.config
+from catalyst.context import namespace
 from catalyst.defaults import (confdefaults, option_messages,
                                DEFAULT_CONFIG_FILE, valid_config_file_values)
 from catalyst.support import CatalystError
@@ -356,15 +355,13 @@ def _main(parser, opts):
     # use pid & user namespaces, but snakeoil's namespace module has signal
     # transfer issues (CTRL+C doesn't propagate), and user namespaces need
     # more work due to Gentoo build process (uses sudo/root/portage).
-    namespaces.simple_unshare(
-        mount=True, uts=True, ipc=True, pid=False, net=False, user=False,
-        hostname='catalyst')
+    with namespace(mount=True, uts=True, ipc=True, hostname='catalyst'):
+        # everything is setup, so the build is a go
+        try:
+            success = build_target(addlargs)
+        except KeyboardInterrupt:
+            log.critical('Catalyst build aborted due to user interrupt 
(Ctrl-C)')
 
-    # everything is setup, so the build is a go
-    try:
-        success = build_target(addlargs)
-    except KeyboardInterrupt:
-        log.critical('Catalyst build aborted due to user interrupt (Ctrl-C)')
     if not success:
         sys.exit(2)
     sys.exit(0)

Reply via email to