diff --git a/mock/docs/site-defaults.cfg b/mock/docs/site-defaults.cfg index d4ea21ad9..53df16a89 100644 --- a/mock/docs/site-defaults.cfg +++ b/mock/docs/site-defaults.cfg @@ -603,3 +603,11 @@ # because by design Mock doesn't have to fully isolate, we disable seccomp for # those containerization tools by default. #config_opts["seccomp"] = False + +# List of usernames (strings) that will be pre-created in buildroot. The UID +# and GID in-chroot is going to be the same as on-host. This option is for +# example useful for the 'pesign' use-cases that both (a) bind-mount +# pesign-owned socket-files into the chroot and (b) install the +# 'BuildRequires: pesign' package which would overwrite the ownership of the +# socket file. See https://github.com/rpm-software-management/mock/issues/1091 +#config_opts["copy_host_users"] = [] diff --git a/mock/py/mockbuild/buildroot.py b/mock/py/mockbuild/buildroot.py index 8e87ee081..b3801be40 100644 --- a/mock/py/mockbuild/buildroot.py +++ b/mock/py/mockbuild/buildroot.py @@ -476,6 +476,11 @@ def _make_users(self): ) self._enable_chrootuser_account() + # Other users + for user in self.config.get("copy_host_users", []): + self.shadow_utils.copy_from_host(user) + + @traceLog() def _enable_chrootuser_account(self): passwd = self.make_chroot_path('/etc/passwd') diff --git a/mock/py/mockbuild/config.py b/mock/py/mockbuild/config.py index aefc115d2..ff53e8ca7 100644 --- a/mock/py/mockbuild/config.py +++ b/mock/py/mockbuild/config.py @@ -333,6 +333,8 @@ def setup_default_config_opts(): config_opts["seccomp"] = False + config_opts["copy_host_users"] = [] + # mapping from target_arch (or forcearch) to arch in /usr/bin/qemu-*-static config_opts["qemu_user_static_mapping"] = { 'aarch64': 'aarch64', diff --git a/mock/py/mockbuild/shadow_utils.py b/mock/py/mockbuild/shadow_utils.py index 2e7b29f58..06cbe200a 100644 --- a/mock/py/mockbuild/shadow_utils.py +++ b/mock/py/mockbuild/shadow_utils.py @@ -59,3 +59,32 @@ def create_user(self, username, uid=None, gid=None, home=None): if home is not None: command += ["-d", str(home)] self._execute_command(command) + + def copy_from_host(self, username): + """ + Copy user (with uid/gid/group_name) from Host into the self.root. + """ + try: + info = pwd.getpwnam(username) + uid = info.pw_uid + gid = info.pw_gid + except KeyError as err: + raise RuntimeError( + f"Can not find the requested user {username} " + "on host") from err + + try: + group_name = grp.getgrgid(gid).gr_name + except KeyError as err: + raise RuntimeError( + f"Can not find the requested GID {gid} " + "on host") from err + + self.delete_user(username, can_fail=True) + # This might fail because the group doesn't exist in the chroot (OK to + # ignore), or because there still are other users in the group (a + # serious error case, but OK to ignore because the subsequent + # 'crate_group' attempt will fail anyway). + self.delete_group(group_name, can_fail=True) + self.create_group(group_name, gid=gid) + self.create_user(group_name, uid=uid, gid=gid)