]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Make InvokingUser just a namespace for functions
authorJoerg Behrmann <behrmann@physik.fu-berlin.de>
Fri, 21 Apr 2023 20:54:26 +0000 (22:54 +0200)
committerJoerg Behrmann <behrmann@physik.fu-berlin.de>
Tue, 25 Apr 2023 12:00:24 +0000 (14:00 +0200)
The sequence of calls to the underlying functions remains the same, but it's
shorter and there are no intermediate dataclass instance constructed.

mkosi/__init__.py
mkosi/config.py
mkosi/run.py
mkosi/util.py

index 929141bc5a7057c13dbdeb2bdcc69b4b721b7a44..a99b86fd10512f481b31a641e1856359d617d11c 100644 (file)
@@ -44,10 +44,10 @@ from mkosi.types import PathString
 from mkosi.util import (
     Compression,
     Distribution,
+    InvokingUser,
     ManifestFormat,
     OutputFormat,
     Verb,
-    current_user,
     flatten,
     format_rlimit,
     patch_file,
@@ -1722,7 +1722,7 @@ def run_shell(config: MkosiConfig) -> None:
         cmdline += ["--"]
         cmdline += config.cmdline
 
-    uid = current_user().uid
+    uid = InvokingUser.uid()
 
     if config.output_format == OutputFormat.directory:
         acl_toggle_remove(config, config.output, uid, allow=False)
@@ -2065,7 +2065,7 @@ def bump_image_version(config: MkosiConfig) -> None:
 
 
 def expand_specifier(s: str) -> str:
-    return s.replace("%u", current_user().name)
+    return s.replace("%u", InvokingUser.name())
 
 
 def needs_build(config: Union[argparse.Namespace, MkosiConfig]) -> bool:
index eb086f2eb173fcb8a2264fbd5c81784d9cf56c59..a24f2f69ca04692c8957705b912c6e7e39338d49 100644 (file)
@@ -23,11 +23,11 @@ from mkosi.run import run
 from mkosi.util import (
     Compression,
     Distribution,
+    InvokingUser,
     ManifestFormat,
     OutputFormat,
     Verb,
     chdir,
-    current_user,
     detect_distribution,
     flatten,
     is_apt_distribution,
@@ -64,11 +64,9 @@ def parse_path(value: str, *, required: bool, absolute: bool = True, expanduser:
     path = Path(value)
 
     if expanduser:
-        user = current_user()
-        if path.is_relative_to("~") and not user.is_running_user():
-            path = user.home / path.relative_to("~")
-        else:
-            path = path.expanduser()
+        if path.is_relative_to("~") and not InvokingUser.is_running_user():
+            path = InvokingUser.home() / path.relative_to("~")
+        path = path.expanduser()
 
     if required and not path.exists():
         die(f"{value} does not exist")
index aaa0b0135b1c0c5c03ad54efbcd62975afffc2b9..32853070a760de416836de2824170acd9a285305 100644 (file)
@@ -17,7 +17,7 @@ from typing import Any, Callable, Mapping, Optional, Sequence, Type, TypeVar
 
 from mkosi.log import ARG_DEBUG, ARG_DEBUG_SHELL, die
 from mkosi.types import _FILE, CompletedProcess, PathString, Popen
-from mkosi.util import current_user
+from mkosi.util import InvokingUser
 
 CLONE_NEWNS = 0x00020000
 CLONE_NEWUSER = 0x10000000
@@ -69,8 +69,7 @@ def become_root() -> tuple[int, int]:
     The function returns the UID-GID pair of the invoking user in the namespace (65436, 65436).
     """
     if os.getuid() == 0:
-        user = current_user()
-        return user.uid, user.gid
+        return InvokingUser.uid_gid()
 
     subuid = read_subrange(Path("/etc/subuid"))
     subgid = read_subrange(Path("/etc/subgid"))
index 5caeb6644921bdfd5c0ca1715db49ad4f6071cf8..dedf5728d9df96da402221c4915467476ab307eb 100644 (file)
@@ -2,7 +2,6 @@
 
 import ast
 import contextlib
-import dataclasses
 import enum
 import functools
 import getpass
@@ -221,49 +220,36 @@ def flatten(lists: Iterable[Iterable[T]]) -> list[T]:
     return list(itertools.chain.from_iterable(lists))
 
 
-@dataclasses.dataclass
 class InvokingUser:
-    _pw: Optional[pwd.struct_passwd] = None
+    @staticmethod
+    def _uid_from_env() -> Optional[str]:
+        return os.getenv("SUDO_UID") or os.getenv("PKEXEC_UID")
 
     @classmethod
-    def for_uid(cls, uid: int) -> "InvokingUser":
-        return cls(pwd.getpwuid(uid))
-
-    @property
-    def uid(self) -> int:
-        if self._pw is not None:
-            return self._pw.pw_uid
-        return os.getuid()
-
-    @property
-    def gid(self) -> int:
-        if self._pw is not None:
-            return self._pw.pw_gid
-        return os.getgid()
-
-    @property
-    def name(self) -> str:
-        if self._pw is not None:
-            return self._pw.pw_name
-        return getpass.getuser()
+    def uid(cls) -> int:
+        return int(cls._uid_from_env() or os.getuid())
 
-    @property
-    def home(self) -> Path:
-        if self._pw is not None:
-            return Path(self._pw.pw_dir)
-        return Path.home()
+    @classmethod
+    def uid_gid(cls) -> tuple[int, int]:
+        if uid := cls._uid_from_env:
+            gid = int(os.getenv("SUDO_GID") or pwd.getpwuid(uid).pw_gid)
+            return uid, gid
+        return os.getuid(), os.getgid()
 
-    def is_running_user(self) -> bool:
-        if self._pw is not None:
-            return self._pw.pw_uid == os.getuid()
-        return True
+    @classmethod
+    def name(cls) -> str:
+        if uid := cls._uid_from_env():
+            return pwd.getpwuid(uid).pw_name
+        return getpass.getuser()
 
+    @classmethod
+    def home(cls) -> Path:
+        home = os.getenv("SUDO_HOME") or os.getenv("HOME") or pwd.getpwuid(cls.uid()).pw_dir
+        return Path(home)
 
-def current_user() -> InvokingUser:
-    uid = os.getenv("SUDO_UID") or os.getenv("PKEXEC_UID")
-    if uid:
-        return InvokingUser.for_uid(int(uid))
-    return InvokingUser()
+    @classmethod
+    def is_running_user(cls) -> bool:
+        return cls.uid() == os.getuid()
 
 
 @contextlib.contextmanager