def expand_specifier(s: str) -> str:
- return s.replace("%u", INVOKING_USER.name)
+ return s.replace("%u", INVOKING_USER.name())
def needs_build(args: MkosiArgs, config: MkosiConfig) -> bool:
from mkosi.config import parse_config
from mkosi.log import ARG_DEBUG, log_setup
from mkosi.run import ensure_exc_info, run
+from mkosi.util import INVOKING_USER
@contextlib.contextmanager
@propagate_failed_return()
def main() -> None:
log_setup()
+ # Ensure that the name and home of the user we are running as are resolved as early as possible.
+ INVOKING_USER.init()
args, images = parse_config(sys.argv[1:])
if args.debug:
if expanduser:
if path.is_relative_to("~") and not INVOKING_USER.is_running_user():
- path = INVOKING_USER.home / path.relative_to("~")
+ path = INVOKING_USER.home() / path.relative_to("~")
path = path.expanduser()
if required and not path.exists():
# directory in /home as well as /home might be on a separate partition or subvolume which means that to take
# advantage of reflinks and such, the workspace directory has to be on the same partition/subvolume.
if (
- Path.cwd().is_relative_to(INVOKING_USER.home) and
- (INVOKING_USER.home / ".cache").exists() and
+ Path.cwd().is_relative_to(INVOKING_USER.home()) and
+ (INVOKING_USER.home() / ".cache").exists() and
(
- self.cache_dir and self.cache_dir.is_relative_to(INVOKING_USER.home) or
- self.output_dir and self.output_dir.is_relative_to(INVOKING_USER.home)
+ self.cache_dir and self.cache_dir.is_relative_to(INVOKING_USER.home()) or
+ self.output_dir and self.output_dir.is_relative_to(INVOKING_USER.home())
)
):
- return INVOKING_USER.home / ".cache"
+ return INVOKING_USER.home() / ".cache"
return Path("/var/tmp")
with tempfile.NamedTemporaryFile(prefix="mkosi.passwd", mode="w") as passwd:
passwd.write("root:x:0:0:root:/root:/bin/sh\n")
if INVOKING_USER.uid != 0:
- name = INVOKING_USER.name
+ name = INVOKING_USER.name()
passwd.write(f"{name}:x:{INVOKING_USER.uid}:{INVOKING_USER.gid}:{name}:/home/{name}:/bin/sh\n")
passwd.flush()
os.fchown(passwd.file.fileno(), INVOKING_USER.uid, INVOKING_USER.gid)
class INVOKING_USER:
uid = int(os.getenv("SUDO_UID") or os.getenv("PKEXEC_UID") or os.getuid())
gid = int(os.getenv("SUDO_GID") or os.getgid())
- name = pwd.getpwuid(uid).pw_name
- home = Path(f"~{name}").expanduser()
invoked_as_root = (uid == 0)
+ @classmethod
+ def init(cls) -> None:
+ name = cls.name()
+ home = cls.home()
+ logging.debug(f"Running as user '{name}' ({cls.uid}:{cls.gid}) with home {home}.")
+
@classmethod
def is_running_user(cls) -> bool:
return cls.uid == os.getuid()
+ @classmethod
+ @functools.lru_cache(maxsize=1)
+ def name(cls) -> str:
+ return pwd.getpwuid(cls.uid).pw_name
+
+ @classmethod
+ @functools.lru_cache(maxsize=1)
+ def home(cls) -> Path:
+ return Path(f"~{cls.name()}").expanduser()
+
@contextlib.contextmanager
def chdir(directory: PathString) -> Iterator[None]: