def __init__(self, plugins, conf, buildroot): self._originalUtilDo = mockbuild.util.do self.buildroot = buildroot self.config = buildroot.config self.state = buildroot.state self.conf = conf self.filesystems = self._selinuxCreateFauxFilesystems() self.chrootFilesystems = buildroot.make_chroot_path( "/proc/filesystems") atexit.register(self._selinuxAtExit) self.buildroot.mounts.add( BindMountPoint(srcpath=self.filesystems, bindpath=self.chrootFilesystems)) self.buildroot.mounts.essential_mounts.append( # essential mounts since we _always_ need to hide it FileSystemMountPoint( filetype='tmpfs', device='mock_hide_selinux_fs', path=buildroot.make_chroot_path('/sys/fs/selinux'))) plugins.add_hook("preyum", self._selinuxPreYumHook) plugins.add_hook("postyum", self._selinuxPostYumHook)
def add_local_repo(config_opts, baseurl, repoid=None, bootstrap=None): if not repoid: repoid = generate_repo_id(baseurl) else: REPOS_ID.append(repoid) localyumrepo = """ [{repoid}] name={baseurl} baseurl={baseurl} enabled=1 skip_if_unavailable=0 metadata_expire=0 cost=1 best=1 """.format(repoid=repoid, baseurl=baseurl) config_opts['{0}.conf'.format( config_opts['package_manager'])] += localyumrepo if bootstrap is None: return if not baseurl.startswith("file:///") and not baseurl.startswith("/"): return local_dir = baseurl.replace("file://", "", 1) if not local_dir or not os.path.isdir(local_dir): return mountpoint = bootstrap.make_chroot_path(local_dir) bootstrap.mounts.add(BindMountPoint(srcpath=local_dir, bindpath=mountpoint))
def __init__(self, plugins, conf, buildroot): self.buildroot = buildroot self.config = buildroot.config self.state = buildroot.state self.bind_opts = conf plugins.add_hook("postinit", self._bindMountCreateDirs) for srcdir, destdir in self.bind_opts['dirs']: buildroot.mounts.add_user_mount( BindMountPoint(srcpath=srcdir, bindpath=buildroot.make_chroot_path(destdir)))
def __init__(self, rootObj, conf): self.rootObj = rootObj self.ccache_opts = conf self.ccachePath = self.ccache_opts['dir'] % self.ccache_opts rootObj.ccacheObj = self rootObj.preExistingDeps.append("ccache") rootObj.addHook("prebuild", self._ccacheBuildHook) rootObj.addHook("preinit", self._ccachePreInitHook) rootObj.mounts.add( BindMountPoint(srcpath=self.ccachePath, bindpath=rootObj.makeChrootPath("/tmp/ccache")))
def __init__(self, rootObj, conf): self.rootObj = rootObj self.bind_opts = conf rootObj.bindMountObj = self rootObj.addHook("preinit", self._bindMountPreInitHook) rootObj.addHook("preshell", self._bindMountPreInitHook) rootObj.addHook("prechroot", self._bindMountPreInitHook) for srcdir, destdir in self.bind_opts['dirs']: rootObj.mounts.add( BindMountPoint(srcpath=srcdir, bindpath=rootObj.makeChrootPath(destdir)))
def __init__(self, plugins, conf, buildroot): self.buildroot = buildroot self.config = buildroot.config self.state = buildroot.state self.ccache_opts = conf tmpdict = self.ccache_opts.copy() tmpdict.update({'chrootuid': self.buildroot.chrootuid}) self.ccachePath = self.ccache_opts['dir'] % tmpdict buildroot.preexisting_deps.append("ccache") plugins.add_hook("prebuild", self._ccacheBuildHook) plugins.add_hook("preinit", self._ccachePreInitHook) buildroot.mounts.add(BindMountPoint(srcpath=self.ccachePath, bindpath=buildroot.make_chroot_path("/tmp/ccache")))
def install_build_results(self, results): self.buildroot.root_log.info("Installing built packages") # Mount resultdir into bootstrap, so we can later install the build # results from there using bootstrap package manager. results_bindmount = None if self.bootstrap_buildroot: resultdir = self.buildroot.resultdir bootstrap_resultdir = self.bootstrap_buildroot.make_chroot_path( resultdir) results_bindmount = BindMountPoint(resultdir, bootstrap_resultdir, options="private") try: self.uid_manager.becomeUser(0, 0) if results_bindmount: results_bindmount.mount() pkgs = [pkg for pkg in results if not pkg.endswith("src.rpm")] try: self.buildroot.install(*pkgs) # pylint: disable=bare-except except: self.buildroot.root_log.warning( "Failed install built packages") finally: if results_bindmount: results_bindmount.umount() self.uid_manager.restorePrivs()
def __init__(self, buildroot, pkg_manager): self.buildroot = buildroot self.cache_path = os.path.join('/var/cache', pkg_manager) self.host_cache_path = os.path.join(self.buildroot.cachedir, pkg_manager + '_cache') self.mount_path = self.buildroot.make_chroot_path(self.cache_path) self.buildroot.mounts.add( BindMountPoint( srcpath=self.host_cache_path, bindpath=self.mount_path, )) mockbuild.util.mkdirIfAbsent(self.host_cache_path)
def __init__(self, plugins, conf, buildroot): self.buildroot = buildroot self.config = buildroot.config self.state = buildroot.state self.bind_opts = conf # Skip mounting user-specified mounts if we're in the boostrap chroot if buildroot.is_bootstrap: return plugins.add_hook("postinit", self._bindMountCreateDirs) for srcdir, destdir in self.bind_opts['dirs']: buildroot.mounts.add_user_mount( BindMountPoint(srcpath=srcdir, bindpath=buildroot.make_chroot_path(destdir)))
def init(self, **kwargs): try: if self.bootstrap_buildroot is not None: # add the extra bind mount to the outer chroot inner_mount = self.bootstrap_buildroot.make_chroot_path(self.buildroot.make_chroot_path()) util.mkdirIfAbsent(self.buildroot.make_chroot_path()) self.bootstrap_buildroot.mounts.managed_mounts.append( BindMountPoint(self.buildroot.make_chroot_path(), inner_mount)) self.bootstrap_buildroot.initialize(**kwargs) self.buildroot.initialize(**kwargs) if not self.buildroot.chroot_was_initialized: self._show_installed_packages() except (KeyboardInterrupt, Exception): self.plugins.call_hooks('initfailed') raise
def __init__(self, plugins, conf, buildroot): self.buildroot = buildroot self.config = buildroot.config self.state = buildroot.state self.yum_cache_opts = conf self.yum_cache_opts['package_manager'] = self.config['package_manager'] self.yumSharedCachePath = self.yum_cache_opts['dir'] % self.yum_cache_opts self.target_path = self.yum_cache_opts['target_dir'] % self.yum_cache_opts self.online = self.config['online'] plugins.add_hook("preyum", self._yumCachePreYumHook) plugins.add_hook("postyum", self._yumCachePostYumHook) plugins.add_hook("preinit", self._yumCachePreInitHook) buildroot.mounts.add(BindMountPoint(srcpath=self.yumSharedCachePath, bindpath=buildroot.make_chroot_path(self.target_path))) mockbuild.util.mkdirIfAbsent(self.yumSharedCachePath) self.yumCacheLock = open(os.path.join(self.yumSharedCachePath, "yumcache.lock"), "a+")
def __init__(self, rootObj, conf): self.rootObj = rootObj self.yum_cache_opts = conf self.yumSharedCachePath = self.yum_cache_opts[ 'dir'] % self.yum_cache_opts self.online = rootObj.online rootObj.yum_cacheObj = self rootObj.addHook("preyum", self._yumCachePreYumHook) rootObj.addHook("postyum", self._yumCachePostYumHook) rootObj.addHook("preinit", self._yumCachePreInitHook) rootObj.mounts.add( BindMountPoint(srcpath=self.yumSharedCachePath, bindpath=rootObj.makeChrootPath('/var/cache/yum'))) mockbuild.util.mkdirIfAbsent(self.yumSharedCachePath) self.yumCacheLock = open( os.path.join(self.yumSharedCachePath, "yumcache.lock"), "a+")
def __init__(self, rootObj, conf): self.rootObj = rootObj self.conf = conf self.filesystems = self._selinuxCreateFauxFilesystems() self.chrootFilesystems = rootObj.makeChrootPath("/proc/filesystems") atexit.register(self._selinuxAtExit) self.rootObj.mounts.add( BindMountPoint(srcpath=self.filesystems, bindpath=self.chrootFilesystems)) if self._selinuxYumIsSetoptSupported(): rootObj.addHook("preyum", self._selinuxPreYumHook) rootObj.addHook("postyum", self._selinuxPostYumHook) else: getLog().warning( "selinux: 'yum' does not support '--setopt' option")
def __init__(self, plugins, conf, buildroot): self._originalUtilDo = mockbuild.util.do self.buildroot = buildroot self.config = buildroot.config self.state = buildroot.state self.conf = conf self.filesystems = self._selinuxCreateFauxFilesystems() self.chrootFilesystems = buildroot.make_chroot_path("/proc/filesystems") atexit.register(self._selinuxAtExit) self.buildroot.mounts.add(BindMountPoint(srcpath=self.filesystems, bindpath=self.chrootFilesystems)) if self._selinuxYumIsSetoptSupported(): plugins.add_hook("preyum", self._selinuxPreYumHook) plugins.add_hook("postyum", self._selinuxPostYumHook) else: getLog().warning("selinux: 'yum' does not support '--setopt' option")
def __init__(self, plugins, conf, buildroot): self._originalUtilDo = mockbuild.util.do self.buildroot = buildroot self.config = buildroot.config self.state = buildroot.state self.conf = conf self.filesystems = self._selinuxCreateFauxFilesystems() self.chrootFilesystems = buildroot.make_chroot_path( "/proc/filesystems") atexit.register(self._selinuxAtExit) self.buildroot.mounts.add( BindMountPoint(srcpath=self.filesystems, bindpath=self.chrootFilesystems)) plugins.add_hook("preyum", self._selinuxPreYumHook) plugins.add_hook("postyum", self._selinuxPostYumHook)
def main(): "Main executable entry point." # initial sanity check for correct invocation method rootcheck() # drop unprivileged to parse args, etc. # uidManager saves current real uid/gid which are unprivileged (callers) # due to suid helper, our current effective uid is 0 # also supports being run by sudo # # setuid wrapper has real uid = unpriv, effective uid = 0 # sudo sets real/effective = 0, and sets env vars # setuid wrapper clears environment, so there wont be any conflict between these two mockgid = grp.getgrnam('mock').gr_gid uidManager = setup_uid_manager(mockgid) # go unpriv only when root to make --help etc work for non-mock users if os.geteuid() == 0: uidManager.dropPrivsTemp() (options, args) = command_parse() if options.printrootpath or options.list_snapshots: options.verbose = 0 # config path -- can be overridden on cmdline config_path = MOCKCONFDIR if options.configdir: config_path = options.configdir config_opts = util.load_config(config_path, options.chroot, uidManager, __VERSION__, PKGPYTHONDIR) config_opts['config_path'] = config_path # cmdline options override config options util.set_config_opts_per_cmdline(config_opts, options, args) # setup 'redhat_subscription_key_id' option before enabling jinja util.subscription_redhat_init(config_opts) # Now when all options are correctly loaded from config files and program # options, turn the jinja templating ON. config_opts['__jinja_expand'] = True # allow a different mock group to be specified if config_opts['chrootgid'] != mockgid: uidManager.restorePrivs() os.setgroups((mockgid, config_opts['chrootgid'])) uidManager.dropPrivsTemp() # verify that our unprivileged uid is in the mock group groupcheck(uidManager.unprivGid, config_opts['chrootgid']) # configure logging setup_logging(config_path, config_opts, options) # verify that we're not trying to build an arch that we can't check_arch_combination(config_opts['rpmbuild_arch'], config_opts) # security cleanup (don't need/want this in the chroot) if 'SSH_AUTH_SOCK' in os.environ: del os.environ['SSH_AUTH_SOCK'] # elevate privs uidManager.become_user_without_push(0, 0) # do whatever we're here to do py_version = '{0}.{1}.{2}'.format(*sys.version_info[:3]) log.info("mock.py version %s starting (python version = %s)...", __VERSION__, py_version) state = State() plugins = Plugins(config_opts, state) # outer buildroot to bootstrap the installation - based on main config with some differences bootstrap_buildroot = None if config_opts['use_bootstrap_container']: # first take a copy of the config so we can make some modifications bootstrap_buildroot_config = config_opts.copy() # copy plugins configuration so we get a separate deep copy bootstrap_buildroot_config['plugin_conf'] = config_opts[ 'plugin_conf'].copy() # pylint: disable=no-member # add '-bootstrap' to the end of the root name bootstrap_buildroot_config[ 'root'] = bootstrap_buildroot_config['root'] + '-bootstrap' # share a yum cache to save downloading everything twice bootstrap_buildroot_config['plugin_conf']['yum_cache_opts']['dir'] = \ "%(cache_topdir)s/" + config_opts['root'] + "/%(package_manager)s_cache/" # we don't want to affect the bootstrap.config['nspawn_args'] array, deep copy bootstrap_buildroot_config['nspawn_args'] = config_opts.get( 'nspawn_args', []).copy() # allow bootstrap buildroot to access the network for getting packages bootstrap_buildroot_config['rpmbuild_networking'] = True bootstrap_buildroot_config['use_host_resolv'] = True util.setup_host_resolv(bootstrap_buildroot_config) # use system_*_command for bootstrapping bootstrap_buildroot_config['yum_command'] = bootstrap_buildroot_config[ 'system_yum_command'] bootstrap_buildroot_config['dnf_command'] = bootstrap_buildroot_config[ 'system_dnf_command'] bootstrap_buildroot_state = State(bootstrap=True) bootstrap_plugins = Plugins(bootstrap_buildroot_config, bootstrap_buildroot_state) bootstrap_buildroot = Buildroot(bootstrap_buildroot_config, uidManager, bootstrap_buildroot_state, bootstrap_plugins, is_bootstrap=True) # this bit of config is needed after we have created the bootstrap buildroot since we need to # query pkg_manager to know which manager is in use bootstrap_buildroot.config[ 'chroot_setup_cmd'] = bootstrap_buildroot.pkg_manager.install_command # override configs for bootstrap_* for k in bootstrap_buildroot.config.copy(): if "bootstrap_" + k in bootstrap_buildroot.config: bootstrap_buildroot.config[k] = bootstrap_buildroot_config[ "bootstrap_" + k] del bootstrap_buildroot.config["bootstrap_" + k] if config_opts['redhat_subscription_required']: key_dir = '/etc/pki/entitlement' chroot_dir = bootstrap_buildroot.make_chroot_path(key_dir) mount_point = BindMountPoint(srcpath=key_dir, bindpath=chroot_dir) bootstrap_buildroot.mounts.add(mount_point) # this changes config_opts['nspawn_args'], so do it after initializing # bootstrap chroot to not inherit the changes there util.setup_host_resolv(config_opts) buildroot = Buildroot(config_opts, uidManager, state, plugins, bootstrap_buildroot) signal.signal(signal.SIGTERM, partial(handle_signals, buildroot)) signal.signal(signal.SIGPIPE, partial(handle_signals, buildroot)) signal.signal(signal.SIGHUP, partial(handle_signals, buildroot)) log.info("Signal handler active") commands = Commands(config_opts, uidManager, plugins, state, buildroot, bootstrap_buildroot) if config_opts['use_bootstrap_container']: bootstrap_buildroot.config[ 'chroot_setup_cmd'] = buildroot.pkg_manager.install_command state.start("run") if options.printrootpath: print(buildroot.make_chroot_path('')) sys.exit(0) if options.list_snapshots: plugins.call_hooks('list_snapshots', required=True) if bootstrap_buildroot is not None: bootstrap_buildroot.plugins.call_hooks('list_snapshots', required=True) sys.exit(0) # dump configuration to log log.debug("mock final configuration:") for k, v in list(config_opts.items()): log.debug(" %s: %s", k, v) os.umask(0o02) os.environ["HOME"] = buildroot.homedir # New namespace starting from here unshare_namespace(config_opts) if config_opts['hostname']: util.sethostname(config_opts['hostname']) # set personality (ie. setarch) util.condPersonality(config_opts['target_arch']) result = 0 try: result = run_command(options, args, config_opts, commands, buildroot, state) finally: buildroot.uid_manager.becomeUser(0, 0) buildroot.finalize() if bootstrap_buildroot is not None: bootstrap_buildroot.finalize() buildroot.uid_manager.restorePrivs() return result