def _install_exit(self, install_phase): if self._default_exit(install_phase) != os.EX_OK: self.wait() return if not os.path.exists(self.settings["D"]): pkg = self.pkg scheduler = self.scheduler settings = self.settings cleanup = 1 # This initializes PORTAGE_LOG_FILE. portage.prepare_build_dirs(pkg.root, settings, cleanup) setup_phase = EbuildPhase(background=self.background, pkg=pkg, phase="setup", scheduler=scheduler, settings=settings, tree=self._tree) setup_phase.addExitListener(self._setup_exit) self._current_task = setup_phase self.scheduler.scheduleSetup(setup_phase) else: self.returncode = os.EX_OK self.wait() return
def _start(self): pkg = self.pkg scheduler = self.scheduler settings = self.settings cleanup = 0 portage.prepare_build_dirs(pkg.root, settings, cleanup) portdb = pkg.root_config.trees['porttree'].dbapi ebuild_path = settings['EBUILD'] mytree = os.path.dirname(os.path.dirname( os.path.dirname(ebuild_path))) alist = portdb.getFetchMap(pkg.cpv, useflags=pkg.use.enabled, mytree=mytree) aalist = portdb.getFetchMap(pkg.cpv, mytree=mytree) settings.configdict["pkg"]["A"] = " ".join(alist) settings.configdict["pkg"]["AA"] = " ".join(aalist) _prepare_fake_distdir(settings, alist) if eapi_exports_replace_vars(settings['EAPI']): vardb = pkg.root_config.trees['vartree'].dbapi settings["REPLACING_VERSIONS"] = " ".join( set(portage.versions.cpv_getversion(match) \ for match in vardb.match(pkg.slot_atom) + \ vardb.match('='+pkg.cpv))) setup_phase = EbuildPhase(background=self.background, phase="setup", scheduler=scheduler, settings=settings) setup_phase.addExitListener(self._setup_exit) self._current_task = setup_phase self.scheduler.scheduleSetup(setup_phase)
def _start(self): pkg = self.pkg scheduler = self.scheduler settings = self.settings cleanup = 0 portage.prepare_build_dirs(pkg.root, settings, cleanup) portdb = pkg.root_config.trees['porttree'].dbapi ebuild_path = settings['EBUILD'] alist = settings.configdict["pkg"].get("A", "").split() _prepare_fake_distdir(settings, alist) if eapi_exports_replace_vars(settings['EAPI']): vardb = pkg.root_config.trees['vartree'].dbapi settings["REPLACING_VERSIONS"] = " ".join( set(portage.versions.cpv_getversion(match) \ for match in vardb.match(pkg.slot_atom) + \ vardb.match('='+pkg.cpv))) setup_phase = EbuildPhase(background=self.background, phase="setup", scheduler=scheduler, settings=settings) setup_phase.addExitListener(self._setup_exit) self._task_queued(setup_phase) self.scheduler.scheduleSetup(setup_phase)
def testDoebuildSpawn(self): playground = ResolverPlayground() try: settings = config(clone=playground.settings) cpv = 'sys-apps/portage-2.1' metadata = { 'EAPI' : '2', 'INHERITED' : 'python eutils', 'IUSE' : 'build doc epydoc python3 selinux', 'LICENSE' : 'GPL-2', 'PROVIDE' : 'virtual/portage', 'RDEPEND' : '>=app-shells/bash-3.2_p17 >=dev-lang/python-2.6', 'SLOT' : '0', } root_config = playground.trees[playground.eroot]['root_config'] pkg = Package(built=False, cpv=cpv, installed=False, metadata=metadata, root_config=root_config, type_name='ebuild') settings.setcpv(pkg) settings['PORTAGE_PYTHON'] = _python_interpreter settings['PORTAGE_BUILDDIR'] = os.path.join( settings['PORTAGE_TMPDIR'], cpv) settings['T'] = os.path.join( settings['PORTAGE_BUILDDIR'], 'temp') for x in ('PORTAGE_BUILDDIR', 'T'): os.makedirs(settings[x]) # Create a fake environment, to pretend as if the ebuild # has been sourced already. open(os.path.join(settings['T'], 'environment'), 'wb').close() scheduler = PollScheduler().sched_iface for phase in ('_internal_test',): # Test EbuildSpawnProcess by calling doebuild.spawn() with # returnpid=False. This case is no longer used by portage # internals since EbuildPhase is used instead and that passes # returnpid=True to doebuild.spawn(). rval = doebuild_spawn("%s %s" % (_shell_quote( os.path.join(settings["PORTAGE_BIN_PATH"], os.path.basename(EBUILD_SH_BINARY))), phase), settings, free=1) self.assertEqual(rval, os.EX_OK) ebuild_phase = EbuildPhase(background=False, phase=phase, scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) ebuild_phase = MiscFunctionsProcess(background=False, commands=['success_hooks'], scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) finally: playground.cleanup()
def _env_extractor_exit(self, env_extractor): if self._default_exit(env_extractor) != os.EX_OK: self._async_unlock_builddir(returncode=self.returncode) return setup_phase = EbuildPhase(background=self.background, phase="setup", scheduler=self.scheduler, settings=self.settings) setup_phase.addExitListener(self._setup_exit) self._task_queued(setup_phase) self.scheduler.scheduleSetup(setup_phase)
def _setup_exit(self, setup_phase): if self._default_exit(setup_phase) != os.EX_OK: self.wait() return unpack_phase = EbuildPhase(background=self.background, phase="unpack", scheduler=self.scheduler, settings=self.settings) if self._live_eclasses.intersection(self.pkg.inherited): # Serialize $DISTDIR access for live ebuilds since # otherwise they can interfere with eachother. unpack_phase.addExitListener(self._unpack_exit) self._current_task = unpack_phase self.scheduler.scheduleUnpack(unpack_phase) else: self._start_task(unpack_phase, self._unpack_exit)
def _env_extractor_exit(self, env_extractor): if self._default_exit(env_extractor) != os.EX_OK: self._unlock_builddir() self.wait() return # This gives bashrc users an opportunity to do various things # such as remove binary packages after they're installed. settings = self.settings settings.setcpv(self.pkg) settings["PORTAGE_BINPKG_FILE"] = self._pkg_path settings.backup_changes("PORTAGE_BINPKG_FILE") setup_phase = EbuildPhase(background=self.background, phase="setup", scheduler=self.scheduler, settings=settings) setup_phase.addExitListener(self._setup_exit) self._current_task = setup_phase self.scheduler.scheduleSetup(setup_phase)
def _clean_phase_exit(self, clean_phase): if self._default_exit(clean_phase) != os.EX_OK: self.wait() return pkg = self.pkg scheduler = self.scheduler settings = self.settings cleanup = 1 # This initializes PORTAGE_LOG_FILE. portage.prepare_build_dirs(pkg.root, settings, cleanup) setup_phase = EbuildPhase(background=self.background, pkg=pkg, phase="setup", scheduler=scheduler, settings=settings, tree=self._tree) setup_phase.addExitListener(self._setup_exit) self._current_task = setup_phase self.scheduler.scheduleSetup(setup_phase)
def _start(self): pkg = self.pkg root_config = pkg.root_config bintree = root_config.trees["bintree"] bintree.prevent_collision(pkg.cpv) binpkg_tmpfile = os.path.join(bintree.pkgdir, pkg.cpv + ".tbz2." + str(os.getpid())) bintree._ensure_dir(os.path.dirname(binpkg_tmpfile)) self._binpkg_tmpfile = binpkg_tmpfile self.settings["PORTAGE_BINPKG_TMPFILE"] = self._binpkg_tmpfile package_phase = EbuildPhase(background=self.background, phase='package', scheduler=self.scheduler, settings=self.settings) self._start_task(package_phase, self._package_phase_exit)
def _fetch_failed(self): # We only call the pkg_nofetch phase if either RESTRICT=fetch # is set or the package has explicitly overridden the default # pkg_nofetch implementation. This allows specialized messages # to be displayed for problematic packages even though they do # not set RESTRICT=fetch (bug #336499). if 'fetch' not in self.pkg.restrict and \ 'nofetch' not in self.pkg.defined_phases: self._async_unlock_builddir(returncode=self.returncode) return self.returncode = None nofetch_phase = EbuildPhase(background=self.background, phase='nofetch', scheduler=self.scheduler, settings=self.settings) self._start_task(nofetch_phase, self._nofetch_exit)
def _build_exit(self, build): if self._default_exit(build) != os.EX_OK: self._unlock_builddir() self.wait() return buildpkg = self._buildpkg if not buildpkg: self._final_exit(build) self.wait() return if self._issyspkg: msg = ">>> This is a system package, " + \ "let's pack a rescue tarball.\n" self.scheduler.output( msg, log_path=self.settings.get("PORTAGE_LOG_FILE")) binpkg_tasks = TaskSequence() requested_binpkg_formats = self.settings.get("PORTAGE_BINPKG_FORMAT", "tar").split() for pkg_fmt in portage.const.SUPPORTED_BINPKG_FORMATS: if pkg_fmt in requested_binpkg_formats: if pkg_fmt == "rpm": binpkg_tasks.add( EbuildPhase(background=self.background, phase="rpm", scheduler=self.scheduler, settings=self.settings)) else: task = EbuildBinpkg(background=self.background, pkg=self.pkg, scheduler=self.scheduler, settings=self.settings) binpkg_tasks.add(task) task.addExitListener(self._record_binpkg_info) if binpkg_tasks: self._start_task(binpkg_tasks, self._buildpkg_exit) return self._final_exit(build) self.wait()
def _verifier_exit(self, verifier): if verifier is not None and \ self._default_exit(verifier) != os.EX_OK: self._unlock_builddir() self.wait() return logger = self.logger pkg = self.pkg pkg_count = self.pkg_count pkg_path = self._pkg_path if self._fetched_pkg: self._bintree.inject(pkg.cpv, filename=pkg_path) logfile = self.settings.get("PORTAGE_LOG_FILE") if logfile is not None and os.path.isfile(logfile): # Remove fetch log after successful fetch. try: os.unlink(logfile) except OSError: pass if self.opts.fetchonly: self._current_task = None self.returncode = os.EX_OK self.wait() return msg = " === (%s of %s) Merging Binary (%s::%s)" % \ (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg_path) short_msg = "emerge: (%s of %s) %s Merge Binary" % \ (pkg_count.curval, pkg_count.maxval, pkg.cpv) logger.log(msg, short_msg=short_msg) phase = "clean" settings = self.settings ebuild_phase = EbuildPhase(background=self.background, phase=phase, scheduler=self.scheduler, settings=settings) self._start_task(ebuild_phase, self._clean_exit)
def _start_pre_clean(self, lock_task): self._assert_current(lock_task) if lock_task.cancelled: self._default_final_exit(lock_task) return lock_task.future.result() # Cleaning needs to happen before fetch, since the build dir # is used for log handling. msg = " === (%s of %s) Cleaning (%s::%s)" % \ (self.pkg_count.curval, self.pkg_count.maxval, self.pkg.cpv, self._ebuild_path) short_msg = "emerge: (%s of %s) %s Clean" % \ (self.pkg_count.curval, self.pkg_count.maxval, self.pkg.cpv) self.logger.log(msg, short_msg=short_msg) pre_clean_phase = EbuildPhase(background=self.background, phase='clean', scheduler=self.scheduler, settings=self.settings) self._start_task(pre_clean_phase, self._pre_clean_exit)
def _unpack_exit(self, unpack_phase): if self._default_exit(unpack_phase) != os.EX_OK: self.wait() return ebuild_phases = TaskSequence(scheduler=self.scheduler) pkg = self.pkg phases = self._phases eapi = pkg.metadata["EAPI"] if not eapi_has_src_prepare_and_src_configure(eapi): # skip src_prepare and src_configure phases = phases[2:] for phase in phases: ebuild_phases.add(EbuildPhase(background=self.background, phase=phase, scheduler=self.scheduler, settings=self.settings)) self._start_task(ebuild_phases, self._default_final_exit)
def testDoebuildSpawn(self): ebuild_body = textwrap.dedent(""" pkg_nofetch() { : ; } """) ebuilds = { 'sys-apps/portage-2.1': { 'EAPI' : '2', 'IUSE' : 'build doc epydoc python3 selinux', 'KEYWORDS' : 'x86', 'LICENSE' : 'GPL-2', 'RDEPEND' : '>=app-shells/bash-3.2_p17 >=dev-lang/python-2.6', 'SLOT' : '0', "MISC_CONTENT": ebuild_body, } } playground = ResolverPlayground(ebuilds=ebuilds) try: root_config = playground.trees[playground.eroot]['root_config'] portdb = root_config.trees["porttree"].dbapi settings = config(clone=playground.settings) if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: settings["__PORTAGE_TEST_HARDLINK_LOCKS"] = \ os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"] settings.backup_changes("__PORTAGE_TEST_HARDLINK_LOCKS") cpv = 'sys-apps/portage-2.1' metadata = dict(zip(Package.metadata_keys, portdb.aux_get(cpv, Package.metadata_keys))) pkg = Package(built=False, cpv=cpv, installed=False, metadata=metadata, root_config=root_config, type_name='ebuild') settings.setcpv(pkg) settings['PORTAGE_PYTHON'] = _python_interpreter settings['PORTAGE_BUILDDIR'] = os.path.join( settings['PORTAGE_TMPDIR'], cpv) settings['PYTHONDONTWRITEBYTECODE'] = os.environ.get('PYTHONDONTWRITEBYTECODE', '') settings['T'] = os.path.join( settings['PORTAGE_BUILDDIR'], 'temp') for x in ('PORTAGE_BUILDDIR', 'T'): os.makedirs(settings[x]) # Create a fake environment, to pretend as if the ebuild # has been sourced already. open(os.path.join(settings['T'], 'environment'), 'wb').close() scheduler = SchedulerInterface(global_event_loop()) for phase in ('_internal_test',): # Test EbuildSpawnProcess by calling doebuild.spawn() with # returnpid=False. This case is no longer used by portage # internals since EbuildPhase is used instead and that passes # returnpid=True to doebuild.spawn(). rval = doebuild_spawn("%s %s" % (_shell_quote( os.path.join(settings["PORTAGE_BIN_PATH"], os.path.basename(EBUILD_SH_BINARY))), phase), settings, free=1) self.assertEqual(rval, os.EX_OK) ebuild_phase = EbuildPhase(background=False, phase=phase, scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) ebuild_phase = MiscFunctionsProcess(background=False, commands=['success_hooks'], scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) spawn_nofetch(portdb, portdb.findname(cpv), settings=settings) finally: playground.cleanup()
def testDoebuildSpawn(self): ebuild_body = textwrap.dedent(""" pkg_nofetch() { : ; } """) ebuilds = { "sys-apps/portage-2.1": { "EAPI": "2", "IUSE": "build doc epydoc python3 selinux", "KEYWORDS": "x86", "LICENSE": "GPL-2", "RDEPEND": ">=app-shells/bash-3.2_p17 >=dev-lang/python-2.6", "SLOT": "0", "MISC_CONTENT": ebuild_body, } } playground = ResolverPlayground(ebuilds=ebuilds) try: root_config = playground.trees[playground.eroot]["root_config"] portdb = root_config.trees["porttree"].dbapi settings = config(clone=playground.settings) if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: settings["__PORTAGE_TEST_HARDLINK_LOCKS"] = os.environ[ "__PORTAGE_TEST_HARDLINK_LOCKS"] settings.backup_changes("__PORTAGE_TEST_HARDLINK_LOCKS") cpv = "sys-apps/portage-2.1" metadata = dict( zip(Package.metadata_keys, portdb.aux_get(cpv, Package.metadata_keys))) pkg = Package( built=False, cpv=cpv, installed=False, metadata=metadata, root_config=root_config, type_name="ebuild", ) settings.setcpv(pkg) settings["PORTAGE_PYTHON"] = _python_interpreter settings["PORTAGE_BUILDDIR"] = os.path.join( settings["PORTAGE_TMPDIR"], cpv) settings["PYTHONDONTWRITEBYTECODE"] = os.environ.get( "PYTHONDONTWRITEBYTECODE", "") settings["HOME"] = os.path.join(settings["PORTAGE_BUILDDIR"], "homedir") settings["T"] = os.path.join(settings["PORTAGE_BUILDDIR"], "temp") for x in ("PORTAGE_BUILDDIR", "HOME", "T"): os.makedirs(settings[x]) # Create a fake environment, to pretend as if the ebuild # has been sourced already. open(os.path.join(settings["T"], "environment"), "wb").close() scheduler = SchedulerInterface(global_event_loop()) for phase in ("_internal_test", ): # Test EbuildSpawnProcess by calling doebuild.spawn() with # returnpid=False. This case is no longer used by portage # internals since EbuildPhase is used instead and that passes # returnpid=True to doebuild.spawn(). rval = doebuild_spawn( "%s %s" % ( _shell_quote( os.path.join( settings["PORTAGE_BIN_PATH"], os.path.basename(EBUILD_SH_BINARY), )), phase, ), settings, free=1, ) self.assertEqual(rval, os.EX_OK) ebuild_phase = EbuildPhase( background=False, phase=phase, scheduler=scheduler, settings=settings, ) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) ebuild_phase = MiscFunctionsProcess( background=False, commands=["success_hooks"], scheduler=scheduler, settings=settings, ) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) spawn_nofetch(portdb, portdb.findname(cpv), settings=settings) finally: playground.cleanup()
def spawn_nofetch(portdb, ebuild_path, settings=None, fd_pipes=None): """ This spawns pkg_nofetch if appropriate. The settings parameter is useful only if setcpv has already been called in order to cache metadata. It will be cloned internally, in order to prevent any changes from interfering with the calling code. If settings is None then a suitable config instance will be acquired from the given portdbapi instance. Do not use the settings parameter unless setcpv has been called on the given instance, since otherwise it's possible to trigger issues like bug #408817 due to fragile assumptions involving the config state inside doebuild_environment(). A private PORTAGE_BUILDDIR will be created and cleaned up, in order to avoid any interference with any other processes. If PORTAGE_TMPDIR is writable, that will be used, otherwise the default directory for the tempfile module will be used. We only call the pkg_nofetch phase if either RESTRICT=fetch is set or the package has explicitly overridden the default pkg_nofetch implementation. This allows specialized messages to be displayed for problematic packages even though they do not set RESTRICT=fetch (bug #336499). This function does nothing if the PORTAGE_PARALLEL_FETCHONLY variable is set in the config instance. """ if settings is None: settings = config(clone=portdb.settings) else: settings = config(clone=settings) if 'PORTAGE_PARALLEL_FETCHONLY' in settings: return os.EX_OK # We must create our private PORTAGE_TMPDIR before calling # doebuild_environment(), since lots of variables such # as PORTAGE_BUILDDIR refer to paths inside PORTAGE_TMPDIR. portage_tmpdir = settings.get('PORTAGE_TMPDIR') if not portage_tmpdir or not os.access(portage_tmpdir, os.W_OK): portage_tmpdir = None private_tmpdir = tempfile.mkdtemp(dir=portage_tmpdir) settings['PORTAGE_TMPDIR'] = private_tmpdir settings.backup_changes('PORTAGE_TMPDIR') # private temp dir was just created, so it's not locked yet settings.pop('PORTAGE_BUILDDIR_LOCKED', None) try: doebuild_environment(ebuild_path, 'nofetch', settings=settings, db=portdb) restrict = settings['PORTAGE_RESTRICT'].split() defined_phases = settings['DEFINED_PHASES'].split() if not defined_phases: # When DEFINED_PHASES is undefined, assume all # phases are defined. defined_phases = EBUILD_PHASES if 'fetch' not in restrict and \ 'nofetch' not in defined_phases: return os.EX_OK prepare_build_dirs(settings=settings) ebuild_phase = EbuildPhase( background=False, phase='nofetch', scheduler=SchedulerInterface( portage._internal_caller and global_event_loop() or EventLoop(main=False)), fd_pipes=fd_pipes, settings=settings) ebuild_phase.start() ebuild_phase.wait() elog_process(settings.mycpv, settings) finally: shutil.rmtree(private_tmpdir) return ebuild_phase.returncode
def _clean_exit(self, clean_phase): if self._default_exit(clean_phase) != os.EX_OK: self._unlock_builddir() self.wait() return dir_path = self._build_dir.dir_path infloc = self._infloc pkg = self.pkg pkg_path = self._pkg_path dir_mode = 0o755 for mydir in (dir_path, self._image_dir, infloc): portage.util.ensure_dirs(mydir, uid=portage.data.portage_uid, gid=portage.data.portage_gid, mode=dir_mode) # This initializes PORTAGE_LOG_FILE. portage.prepare_build_dirs(self.settings["ROOT"], self.settings, 1) self._writemsg_level(">>> Extracting info\n") pkg_xpak = portage.xpak.tbz2(self._pkg_path) check_missing_metadata = ("CATEGORY", "PF") missing_metadata = set() for k in check_missing_metadata: v = pkg_xpak.getfile(_unicode_encode(k, encoding=_encodings['repo.content'])) if not v: missing_metadata.add(k) pkg_xpak.unpackinfo(infloc) for k in missing_metadata: if k == "CATEGORY": v = pkg.category elif k == "PF": v = pkg.pf else: continue f = codecs.open(_unicode_encode(os.path.join(infloc, k), encoding=_encodings['fs'], errors='strict'), mode='w', encoding=_encodings['content'], errors='replace') try: f.write(v + "\n") finally: f.close() # Store the md5sum in the vdb. f = codecs.open(_unicode_encode(os.path.join(infloc, 'BINPKGMD5'), encoding=_encodings['fs'], errors='strict'), mode='w', encoding=_encodings['content'], errors='strict') try: f.write(str(portage.checksum.perform_md5(pkg_path)) + "\n") finally: f.close() # This gives bashrc users an opportunity to do various things # such as remove binary packages after they're installed. settings = self.settings settings.setcpv(self.pkg) settings["PORTAGE_BINPKG_FILE"] = pkg_path settings.backup_changes("PORTAGE_BINPKG_FILE") phase = "setup" setup_phase = EbuildPhase(background=self.background, pkg=self.pkg, phase=phase, scheduler=self.scheduler, settings=settings, tree=self._tree) setup_phase.addExitListener(self._setup_exit) self._current_task = setup_phase self.scheduler.scheduleSetup(setup_phase)
def testDoebuildSpawn(self): ebuild_body = textwrap.dedent(""" pkg_nofetch() { : ; } """) ebuilds = { 'sys-apps/portage-2.1': { 'EAPI': '2', 'IUSE': 'build doc epydoc python3 selinux', 'KEYWORDS': 'x86', 'LICENSE': 'GPL-2', 'RDEPEND': '>=app-shells/bash-3.2_p17 >=dev-lang/python-2.6', 'SLOT': '0', "MISC_CONTENT": ebuild_body, } } playground = ResolverPlayground(ebuilds=ebuilds) try: root_config = playground.trees[playground.eroot]['root_config'] portdb = root_config.trees["porttree"].dbapi settings = config(clone=playground.settings) if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: settings["__PORTAGE_TEST_HARDLINK_LOCKS"] = \ os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"] settings.backup_changes("__PORTAGE_TEST_HARDLINK_LOCKS") cpv = 'sys-apps/portage-2.1' metadata = dict( zip(Package.metadata_keys, portdb.aux_get(cpv, Package.metadata_keys))) pkg = Package(built=False, cpv=cpv, installed=False, metadata=metadata, root_config=root_config, type_name='ebuild') settings.setcpv(pkg) settings['PORTAGE_PYTHON'] = _python_interpreter settings['PORTAGE_BUILDDIR'] = os.path.join( settings['PORTAGE_TMPDIR'], cpv) settings['T'] = os.path.join(settings['PORTAGE_BUILDDIR'], 'temp') for x in ('PORTAGE_BUILDDIR', 'T'): os.makedirs(settings[x]) # Create a fake environment, to pretend as if the ebuild # has been sourced already. open(os.path.join(settings['T'], 'environment'), 'wb').close() scheduler = SchedulerInterface(global_event_loop()) for phase in ('_internal_test', ): # Test EbuildSpawnProcess by calling doebuild.spawn() with # returnpid=False. This case is no longer used by portage # internals since EbuildPhase is used instead and that passes # returnpid=True to doebuild.spawn(). rval = doebuild_spawn("%s %s" % (_shell_quote( os.path.join(settings["PORTAGE_BIN_PATH"], os.path.basename(EBUILD_SH_BINARY))), phase), settings, free=1) self.assertEqual(rval, os.EX_OK) ebuild_phase = EbuildPhase(background=False, phase=phase, scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) ebuild_phase = MiscFunctionsProcess(background=False, commands=['success_hooks'], scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) spawn_nofetch(portdb, portdb.findname(cpv), settings=settings) finally: playground.cleanup()
def _verifier_exit(self, verifier): if verifier is not None and self._default_exit(verifier) != os.EX_OK: self._async_unlock_builddir(returncode=self.returncode) return logger = self.logger pkg = self.pkg pkg_count = self.pkg_count if self._fetched_pkg: pkg_path = self._bintree.getname( self._bintree.inject(pkg.cpv, filename=self._fetched_pkg), allocate_new=False, ) else: pkg_path = self.pkg.root_config.trees["bintree"].getname( self.pkg.cpv) # This gives bashrc users an opportunity to do various things # such as remove binary packages after they're installed. if pkg_path is not None: self.settings["PORTAGE_BINPKG_FILE"] = pkg_path self._pkg_path = pkg_path logfile = self.settings.get("PORTAGE_LOG_FILE") if logfile is not None and os.path.isfile(logfile): # Remove fetch log after successful fetch. try: os.unlink(logfile) except OSError: pass if self.opts.fetchonly: self._current_task = None self.returncode = os.EX_OK self.wait() return msg = " === (%s of %s) Merging Binary (%s::%s)" % ( pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg_path, ) short_msg = "emerge: (%s of %s) %s Merge Binary" % ( pkg_count.curval, pkg_count.maxval, pkg.cpv, ) logger.log(msg, short_msg=short_msg) phase = "clean" settings = self.settings ebuild_phase = EbuildPhase( background=self.background, phase=phase, scheduler=self.scheduler, settings=settings, ) self._start_task(ebuild_phase, self._clean_exit)
def spawn_nofetch(portdb, ebuild_path, settings=None): """ This spawns pkg_nofetch if appropriate. The settings parameter is useful only if setcpv has already been called in order to cache metadata. It will be cloned internally, in order to prevent any changes from interfering with the calling code. If settings is None then a suitable config instance will be acquired from the given portdbapi instance. A private PORTAGE_BUILDDIR will be created and cleaned up, in order to avoid any interference with any other processes. If PORTAGE_TMPDIR is writable, that will be used, otherwise the default directory for the tempfile module will be used. We only call the pkg_nofetch phase if either RESTRICT=fetch is set or the package has explicitly overridden the default pkg_nofetch implementation. This allows specialized messages to be displayed for problematic packages even though they do not set RESTRICT=fetch (bug #336499). This function does nothing if the PORTAGE_PARALLEL_FETCHONLY variable is set in the config instance. """ if settings is None: settings = config(clone=portdb.settings) else: settings = config(clone=settings) if 'PORTAGE_PARALLEL_FETCHONLY' in settings: return # We must create our private PORTAGE_TMPDIR before calling # doebuild_environment(), since lots of variables such # as PORTAGE_BUILDDIR refer to paths inside PORTAGE_TMPDIR. portage_tmpdir = settings.get('PORTAGE_TMPDIR') if not portage_tmpdir or not os.access(portage_tmpdir, os.W_OK): portage_tmpdir = None private_tmpdir = tempfile.mkdtemp(dir=portage_tmpdir) settings['PORTAGE_TMPDIR'] = private_tmpdir settings.backup_changes('PORTAGE_TMPDIR') # private temp dir was just created, so it's not locked yet settings.pop('PORTAGE_BUILDIR_LOCKED', None) try: doebuild_environment(ebuild_path, 'nofetch', settings=settings, db=portdb) restrict = settings['PORTAGE_RESTRICT'].split() defined_phases = settings['DEFINED_PHASES'].split() if not defined_phases: # When DEFINED_PHASES is undefined, assume all # phases are defined. defined_phases = EBUILD_PHASES if 'fetch' not in restrict and \ 'nofetch' not in defined_phases: return prepare_build_dirs(settings=settings) ebuild_phase = EbuildPhase(background=False, phase='nofetch', scheduler=PollScheduler().sched_iface, settings=settings) ebuild_phase.start() ebuild_phase.wait() elog_process(settings.mycpv, settings) finally: shutil.rmtree(private_tmpdir)
def testDoebuildSpawn(self): playground = ResolverPlayground() try: settings = config(clone=playground.settings) if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: settings["__PORTAGE_TEST_HARDLINK_LOCKS"] = \ os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"] settings.backup_changes("__PORTAGE_TEST_HARDLINK_LOCKS") cpv = 'sys-apps/portage-2.1' metadata = { 'EAPI' : '2', 'INHERITED' : 'python eutils', 'IUSE' : 'build doc epydoc python3 selinux', 'KEYWORDS' : 'x86', 'LICENSE' : 'GPL-2', 'PROVIDE' : 'virtual/portage', 'RDEPEND' : '>=app-shells/bash-3.2_p17 >=dev-lang/python-2.6', 'SLOT' : '0', 'repository': 'gentoo', } root_config = playground.trees[playground.eroot]['root_config'] pkg = Package(built=False, cpv=cpv, installed=False, metadata=metadata, root_config=root_config, type_name='ebuild') settings.setcpv(pkg) settings['PORTAGE_PYTHON'] = _python_interpreter settings['PORTAGE_BUILDDIR'] = os.path.join( settings['PORTAGE_TMPDIR'], cpv) settings['T'] = os.path.join( settings['PORTAGE_BUILDDIR'], 'temp') for x in ('PORTAGE_BUILDDIR', 'T'): os.makedirs(settings[x]) # Create a fake environment, to pretend as if the ebuild # has been sourced already. open(os.path.join(settings['T'], 'environment'), 'wb').close() scheduler = PollScheduler().sched_iface for phase in ('_internal_test',): # Test EbuildSpawnProcess by calling doebuild.spawn() with # returnpid=False. This case is no longer used by portage # internals since EbuildPhase is used instead and that passes # returnpid=True to doebuild.spawn(). rval = doebuild_spawn("%s %s" % (_shell_quote( os.path.join(settings["PORTAGE_BIN_PATH"], os.path.basename(EBUILD_SH_BINARY))), phase), settings, free=1) self.assertEqual(rval, os.EX_OK) ebuild_phase = EbuildPhase(background=False, phase=phase, scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) ebuild_phase = MiscFunctionsProcess(background=False, commands=['success_hooks'], scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) finally: playground.cleanup()