From: Quentin Deslandes Date: Tue, 18 Oct 2022 17:10:32 +0000 (+0200) Subject: chown mkosi-generated directories X-Git-Tag: v14~1^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e313e0081bb359924c0a852671a860fbb695da33;p=thirdparty%2Fmkosi.git chown mkosi-generated directories 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. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 74afefc08..b6a3dfbc6 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -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]: diff --git a/mkosi/backend.py b/mkosi/backend.py index d2070f544..25c841057 100644 --- a/mkosi/backend.py +++ b/mkosi/backend.py @@ -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)