]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Revert back to shell based chmod solution for bwrap
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 24 Apr 2023 13:11:11 +0000 (15:11 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 24 Apr 2023 14:54:24 +0000 (16:54 +0200)
Mounting the host directories doesn't work because those directories
are owned by root on the host which translates to nobody in the user
namespace, breaking systemd tmpfiles tests.

mkosi/run.py

index 80328fff537523c2152b413f53375c03de82f1ad..9522801dfd132ae68011405979b70f2e9787ef4d 100644 (file)
@@ -288,12 +288,10 @@ def bwrap(
     if apivfs:
         cmdline += [
             "--tmpfs", apivfs / "run",
+            "--tmpfs", apivfs / "tmp",
             "--proc", apivfs / "proc",
             "--dev", apivfs / "dev",
             "--ro-bind", "/sys", apivfs / "sys",
-            "--bind", "/tmp", apivfs / "tmp",
-            "--bind", "/var/tmp", apivfs / "var/tmp",
-            "--bind", "/dev/shm", apivfs / "dev/shm",
         ]
 
         # If passwd or a related file exists in the apivfs directory, bind mount it over the host files while
@@ -307,12 +305,25 @@ def bwrap(
             else:
                 cmdline += ["--bind", "/dev/null", f"/etc/{f}"]
 
-    try:
-        return run([*cmdline, *cmd], text=True, stdout=stdout, env=env, log=False)
-    except subprocess.CalledProcessError as e:
-        if ARG_DEBUG_SHELL.get():
-            run([*cmdline, "sh"], stdin=sys.stdin, check=False, env=env, log=False)
-        die(f'"{shlex.join(str(s) for s in cmd)}" returned non-zero exit code {e.returncode}.')
+    if apivfs:
+        chmod = f"chmod 1777 {apivfs / 'tmp'} {apivfs / 'var/tmp'} {apivfs / 'dev/shm'}"
+    else:
+        chmod = ":"
+
+    with tempfile.TemporaryDirectory(dir="/var/tmp", prefix="mkosi-var-tmp") as var_tmp:
+        if apivfs:
+            cmdline += ["--bind", var_tmp, apivfs / "var/tmp"]
+
+        cmdline += ["sh", "-c"]
+        template = f"{chmod} && exec {{}} || exit $?"
+
+        try:
+            return run([*cmdline, template.format(shlex.join(str(s) for s in cmd))],
+                       text=True, stdout=stdout, env=env, log=False)
+        except subprocess.CalledProcessError as e:
+            if ARG_DEBUG_SHELL.get():
+                run([*cmdline, template.format("sh")], stdin=sys.stdin, check=False, env=env, log=False)
+            die(f'"{shlex.join(str(s) for s in cmd)}" returned non-zero exit code {e.returncode}.')
 
 
 def run_workspace_command(
@@ -330,12 +341,10 @@ def run_workspace_command(
         "--unshare-cgroup",
         "--bind", root, "/",
         "--tmpfs", "/run",
+        "--tmpfs", "/tmp",
         "--dev", "/dev",
         "--proc", "/proc",
         "--ro-bind", "/sys", "/sys",
-        "--bind", "/tmp", "/tmp",
-        "--bind", "/var/tmp", "/var/tmp",
-        "--bind", "/dev/shm", "/dev/shm",
         "--die-with-parent",
         *bwrap_params,
     ]
@@ -362,13 +371,20 @@ def run_workspace_command(
         PATH="/usr/bin:/usr/sbin",
     ) | env
 
-    try:
-        return run([*cmdline, *cmd], text=True, stdout=stdout, env=env, log=False)
-    except subprocess.CalledProcessError as e:
-        if ARG_DEBUG_SHELL.get():
-            run([*cmdline, "sh"], stdin=sys.stdin, check=False, env=env, log=False)
-        die(f'"{shlex.join(str(s) for s in cmd)}" returned non-zero exit code {e.returncode}.')
-    finally:
-        if tmp.is_symlink():
-            resolve.unlink(missing_ok=True)
-            shutil.move(tmp, resolve)
+    with tempfile.TemporaryDirectory(dir="/var/tmp", prefix="mkosi-var-tmp") as var_tmp:
+        cmdline += ["--bind", var_tmp, "/var/tmp"]
+
+        cmdline += ["sh", "-c"]
+        template = "chmod 1777 /tmp /var/tmp /dev/shm && exec {} || exit $?"
+
+        try:
+            return run([*cmdline, template.format(shlex.join(str(s) for s in cmd))],
+                       text=True, stdout=stdout, env=env, log=False)
+        except subprocess.CalledProcessError as e:
+            if ARG_DEBUG_SHELL.get():
+                run([*cmdline, template.format("sh")], stdin=sys.stdin, check=False, env=env, log=False)
+            die(f'"{shlex.join(str(s) for s in cmd)}" returned non-zero exit code {e.returncode}.')
+        finally:
+            if tmp.is_symlink():
+                resolve.unlink(missing_ok=True)
+                shutil.move(tmp, resolve)