]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
chown mkosi-generated directories
authorQuentin Deslandes <qde@naccy.de>
Tue, 18 Oct 2022 17:10:32 +0000 (19:10 +0200)
committerQuentin Deslandes <qde@naccy.de>
Thu, 27 Oct 2022 09:47:37 +0000 (11:47 +0200)
Change the owner of directories created by mkosi, unless --no-chown is
used. Directories owner will be set to SUDO_UID or PKEXEC_UID if
defined, or to current UID otherwise.

mkosi/__init__.py
mkosi/backend.py

index 74afefc083d7554a6538b1a79ffc412f2a6f0a33..b6a3dfbc66ea34ede8879425f98628436e5f34af 100644 (file)
@@ -79,10 +79,12 @@ from .backend import (
     PartitionTable,
     SourceFileTransfer,
     Verb,
+    chown_to_running_user,
     die,
     is_centos_variant,
     is_epel_variant,
     is_rpm_distribution,
+    mkdirp_chown_current_user,
     nspawn_knows_arg,
     nspawn_rlimit_params,
     nspawn_version,
@@ -4449,6 +4451,9 @@ def save_cache(state: MkosiState, raw: Optional[str], cache_path: Optional[Path]
             unlink_try_hard(cache_path)
             shutil.move(cast(str, state.root), cache_path)  # typing bug, .move() accepts Path
 
+    if not state.config.no_chown:
+        chown_to_running_user(cache_path)
+
 
 def _link_output(
         config: MkosiConfig,
@@ -4467,19 +4472,8 @@ def _link_output(
     if config.no_chown:
         return
 
-    sudo_uid = os.getenv("SUDO_UID")
-    sudo_gid = os.getenv("SUDO_GID")
-    if not (sudo_uid and sudo_gid):
-        return
-
     relpath = path_relative_to_cwd(newpath)
-
-    sudo_user = os.getenv("SUDO_USER", default=sudo_uid)
-    with complete_step(
-        f"Changing ownership of output file {relpath} to user {sudo_user} (acquired from sudo)…",
-        f"Changed ownership of {relpath}",
-    ):
-        os.chown(newpath, int(sudo_uid), int(sudo_gid))
+    chown_to_running_user(relpath)
 
 
 def link_output(state: MkosiState, artifact: Optional[BinaryIO]) -> None:
@@ -4681,8 +4675,7 @@ def setup_package_cache(config: MkosiConfig, workspace: Path) -> Path:
         cache = workspace / "cache"
     else:
         cache = config.cache_path
-
-    os.makedirs(cache, 0o755, exist_ok=True)
+        mkdirp_chown_current_user(cache, skip_chown=config.no_chown, mode=0o755)
 
     return cache
 
@@ -6252,7 +6245,7 @@ def find_output(args: argparse.Namespace) -> None:
     else:
         return
 
-    args.output_dir.mkdir(parents=True, exist_ok=True)
+    mkdirp_chown_current_user(args.output_dir, skip_chown=args.no_chown)
 
 
 def find_builddir(args: argparse.Namespace) -> None:
@@ -6265,7 +6258,7 @@ def find_builddir(args: argparse.Namespace) -> None:
     else:
         return
 
-    args.build_dir.mkdir(parents=True, exist_ok=True)
+    mkdirp_chown_current_user(args.build_dir, skip_chown=args.no_chown)
 
 
 def find_cache(args: argparse.Namespace) -> None:
@@ -6278,7 +6271,7 @@ def find_cache(args: argparse.Namespace) -> None:
     else:
         return
 
-    args.cache_path.mkdir(parents=True, exist_ok=True)
+    mkdirp_chown_current_user(args.cache_path, skip_chown=args.no_chown)
 
 
 def require_private_file(name: str, description: str) -> None:
@@ -7049,7 +7042,7 @@ def make_output_dir(config: MkosiConfig) -> None:
     if config.output_dir is None:
         return
 
-    config.output_dir.mkdir(mode=0o755, exist_ok=True)
+    mkdirp_chown_current_user(config.output_dir, skip_chown=config.no_chown, mode=0o755)
 
 
 def make_build_dir(config: MkosiConfig) -> None:
@@ -7057,7 +7050,7 @@ def make_build_dir(config: MkosiConfig) -> None:
     if config.build_dir is None:
         return
 
-    config.build_dir.mkdir(mode=0o755, exist_ok=True)
+    mkdirp_chown_current_user(config.build_dir, skip_chown=config.no_chown, mode=0o755)
 
 
 def configure_ssh(state: MkosiState, cached: bool) -> Optional[TextIO]:
index d2070f544cfbf238b340acd3198d1d9c5d241aef..25c841057897f31f565d10008ee1bccdafe82b7d 100644 (file)
@@ -10,6 +10,7 @@ import errno
 import math
 import os
 import platform
+import pwd
 import resource
 import shlex
 import shutil
@@ -948,3 +949,38 @@ class MkosiPrinter:
 
         if text2 is not None:
             cls.print_step(text2.format(*args))
+
+
+def chown_to_running_user(path: PathString) -> None:
+    uid = int(os.getenv("SUDO_UID") or os.getenv("PKEXEC_UID") or str(os.getuid()))
+    user = pwd.getpwuid(uid).pw_name
+    gid = pwd.getpwuid(uid).pw_gid
+
+    with MkosiPrinter.complete_step(
+        f"Changing ownership of output file {path} to user {user}…",
+        f"Changed ownership of {path}",
+    ):
+        os.chown(path, uid, gid)
+
+
+def mkdirp_chown_current_user(
+    path: PathString,
+    *,
+    skip_chown: bool = False,
+    mode: int = 0o777,
+    exist_ok: bool = True
+) -> None:
+    abspath = Path(path).absolute()
+    path = Path()
+
+    for d in abspath.parts:
+        path /= d
+        if path.exists():
+            continue
+
+        path.mkdir(mode=mode, exist_ok=exist_ok)
+
+        if skip_chown:
+            continue
+
+        chown_to_running_user(path)