def eapi_invalid(self, cpv, repo_name, settings, eapi_var, eapi_parsed, eapi_lineno): msg = [] msg.extend(textwrap.wrap(("EAPI assignment in ebuild '%s%s%s' does not" " conform with PMS section 7.3.1 (see bug #402167):") % (cpv, _repo_separator, repo_name), 70)) if not eapi_parsed: # None means the assignment was not found, while an # empty string indicates an (invalid) empty assingment. msg.append( "\tvalid EAPI assignment must" " occur on or before line: %s" % eapi_lineno) else: msg.append(("\tbash returned EAPI '%s' which does not match " "assignment on line: %s") % (eapi_var, eapi_lineno)) if portage.data.secpass >= 2: # TODO: improve elog permission error handling (bug #416231) for line in msg: eerror(line, phase="other", key=cpv) elog_process(cpv, settings, phasefilter=("other",)) else: out = portage.output.EOutput() for line in msg: out.eerror(line)
def eapi_invalid(self, cpv, repo_name, settings, eapi_var, eapi_parsed, eapi_lineno): msg = [] msg.extend( textwrap.wrap( ("EAPI assignment in ebuild '%s%s%s' does not" " conform with PMS section 7.3.1 (see bug #402167):") % (cpv, _repo_separator, repo_name), 70, )) if not eapi_parsed: # None means the assignment was not found, while an # empty string indicates an (invalid) empty assingment. msg.append("\tvalid EAPI assignment must" " occur on or before line: %s" % eapi_lineno) else: msg.append(("\tbash returned EAPI '%s' which does not match " "assignment on line: %s") % (eapi_var, eapi_lineno)) if portage.data.secpass >= 2: # TODO: improve elog permission error handling (bug #416231) for line in msg: eerror(line, phase="other", key=cpv) elog_process(cpv, settings, phasefilter=("other", )) else: out = portage.output.EOutput() for line in msg: out.eerror(line)
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 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 pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes=None, blockers=None): """will merge a .tbz2 file, returning a list of runtime dependencies that must be satisfied, or None if there was a merge error. This code assumes the package exists.""" warnings.warn("portage.pkgmerge() is deprecated", DeprecationWarning, stacklevel=2) if mydbapi is None: mydbapi = portage.db[myroot]["bintree"].dbapi if vartree is None: vartree = portage.db[myroot]["vartree"] if mytbz2[-5:] != ".tbz2": print(_("!!! Not a .tbz2 file")) return 1 tbz2_lock = None mycat = None mypkg = None did_merge_phase = False success = False try: """ Don't lock the tbz2 file because the filesytem could be readonly or shared by a cluster.""" # tbz2_lock = portage.locks.lockfile(mytbz2, wantnewlockfile=1) mypkg = os.path.basename(mytbz2)[:-5] xptbz2 = portage.xpak.tbz2(mytbz2) mycat = xptbz2.getfile(_unicode_encode("CATEGORY", encoding=_encodings["repo.content"])) if not mycat: writemsg(_("!!! CATEGORY info missing from info chunk, aborting...\n"), noiselevel=-1) return 1 mycat = _unicode_decode(mycat, encoding=_encodings["repo.content"], errors="replace") mycat = mycat.strip() # These are the same directories that would be used at build time. builddir = os.path.join(mysettings["PORTAGE_TMPDIR"], "portage", mycat, mypkg) catdir = os.path.dirname(builddir) pkgloc = os.path.join(builddir, "image") infloc = os.path.join(builddir, "build-info") myebuild = os.path.join(infloc, os.path.basename(mytbz2)[:-4] + "ebuild") portage.util.ensure_dirs(os.path.dirname(catdir), uid=portage_uid, gid=portage_gid, mode=0o70, mask=0) portage.util.ensure_dirs(catdir, uid=portage_uid, gid=portage_gid, mode=0o70, mask=0) try: shutil.rmtree(builddir) except (IOError, OSError) as e: if e.errno != errno.ENOENT: raise del e for mydir in (builddir, pkgloc, infloc): portage.util.ensure_dirs(mydir, uid=portage_uid, gid=portage_gid, mode=0o755) writemsg_stdout(_(">>> Extracting info\n")) xptbz2.unpackinfo(infloc) mysettings.setcpv(mycat + "/" + mypkg, mydb=mydbapi) # Store the md5sum in the vdb. fp = open(_unicode_encode(os.path.join(infloc, "BINPKGMD5")), "w") fp.write(str(portage.checksum.perform_md5(mytbz2)) + "\n") fp.close() # This gives bashrc users an opportunity to do various things # such as remove binary packages after they're installed. mysettings["PORTAGE_BINPKG_FILE"] = mytbz2 mysettings.backup_changes("PORTAGE_BINPKG_FILE") debug = mysettings.get("PORTAGE_DEBUG", "") == "1" # Eventually we'd like to pass in the saved ebuild env here. retval = portage.doebuild( myebuild, "setup", myroot, mysettings, debug=debug, tree="bintree", mydbapi=mydbapi, vartree=vartree ) if retval != os.EX_OK: writemsg(_("!!! Setup failed: %s\n") % retval, noiselevel=-1) return retval writemsg_stdout(_(">>> Extracting %s\n") % mypkg) retval = portage.process.spawn_bash( "bzip2 -dqc -- '%s' | tar -xp -C '%s' -f -" % (mytbz2, pkgloc), env=mysettings.environ() ) if retval != os.EX_OK: writemsg(_("!!! Error Extracting '%s'\n") % mytbz2, noiselevel=-1) return retval # portage.locks.unlockfile(tbz2_lock) # tbz2_lock = None mylink = portage.dblink( mycat, mypkg, myroot, mysettings, vartree=vartree, treetype="bintree", blockers=blockers ) retval = mylink.merge(pkgloc, infloc, myroot, myebuild, cleanup=0, mydbapi=mydbapi, prev_mtimes=prev_mtimes) did_merge_phase = True success = retval == os.EX_OK return retval finally: mysettings.pop("PORTAGE_BINPKG_FILE", None) if tbz2_lock: portage.locks.unlockfile(tbz2_lock) if True: if not did_merge_phase: # The merge phase handles this already. Callers don't know how # far this function got, so we have to call elog_process() here # so that it's only called once. from portage.elog import elog_process elog_process(mycat + "/" + mypkg, mysettings) try: if success: shutil.rmtree(builddir) except (IOError, OSError) as e: if e.errno != errno.ENOENT: raise del e
def _nofetch_exit(self, ebuild_phase): self._final_exit(ebuild_phase) elog_process(self.settings.mycpv, self.settings) shutil.rmtree(self._private_tmpdir) self._async_wait()
def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes=None, blockers=None): """will merge a .tbz2 file, returning a list of runtime dependencies that must be satisfied, or None if there was a merge error. This code assumes the package exists.""" warnings.warn("portage.pkgmerge() is deprecated", DeprecationWarning, stacklevel=2) if mydbapi is None: mydbapi = portage.db[myroot]["bintree"].dbapi if vartree is None: vartree = portage.db[myroot]["vartree"] if mytbz2[-5:] != ".tbz2": print(_("!!! Not a .tbz2 file")) return 1 tbz2_lock = None mycat = None mypkg = None did_merge_phase = False success = False try: """ Don't lock the tbz2 file because the filesytem could be readonly or shared by a cluster.""" #tbz2_lock = portage.locks.lockfile(mytbz2, wantnewlockfile=1) mypkg = os.path.basename(mytbz2)[:-5] xptbz2 = portage.xpak.tbz2(mytbz2) mycat = xptbz2.getfile( _unicode_encode("CATEGORY", encoding=_encodings['repo.content'])) if not mycat: writemsg( _("!!! CATEGORY info missing from info chunk, aborting...\n"), noiselevel=-1) return 1 mycat = _unicode_decode(mycat, encoding=_encodings['repo.content'], errors='replace') mycat = mycat.strip() # These are the same directories that would be used at build time. builddir = os.path.join(mysettings["PORTAGE_TMPDIR"], "portage", mycat, mypkg) catdir = os.path.dirname(builddir) pkgloc = os.path.join(builddir, "image") infloc = os.path.join(builddir, "build-info") myebuild = os.path.join(infloc, os.path.basename(mytbz2)[:-4] + "ebuild") portage.util.ensure_dirs(os.path.dirname(catdir), uid=portage_uid, gid=portage_gid, mode=0o70, mask=0) portage.util.ensure_dirs(catdir, uid=portage_uid, gid=portage_gid, mode=0o70, mask=0) try: shutil.rmtree(builddir) except (IOError, OSError) as e: if e.errno != errno.ENOENT: raise del e for mydir in (builddir, pkgloc, infloc): portage.util.ensure_dirs(mydir, uid=portage_uid, gid=portage_gid, mode=0o755) writemsg_stdout(_(">>> Extracting info\n")) xptbz2.unpackinfo(infloc) mysettings.setcpv(mycat + "/" + mypkg, mydb=mydbapi) # Store the md5sum in the vdb. fp = open(_unicode_encode(os.path.join(infloc, 'BINPKGMD5')), 'w') fp.write(str(portage.checksum.perform_md5(mytbz2)) + "\n") fp.close() # This gives bashrc users an opportunity to do various things # such as remove binary packages after they're installed. mysettings["PORTAGE_BINPKG_FILE"] = mytbz2 mysettings.backup_changes("PORTAGE_BINPKG_FILE") debug = mysettings.get("PORTAGE_DEBUG", "") == "1" # Eventually we'd like to pass in the saved ebuild env here. retval = portage.doebuild(myebuild, "setup", myroot, mysettings, debug=debug, tree="bintree", mydbapi=mydbapi, vartree=vartree) if retval != os.EX_OK: writemsg(_("!!! Setup failed: %s\n") % retval, noiselevel=-1) return retval writemsg_stdout(_(">>> Extracting %s\n") % mypkg) retval = portage.process.spawn_bash( "bzip2 -dqc -- '%s' | tar -xp -C '%s' -f -" % (mytbz2, pkgloc), env=mysettings.environ()) if retval != os.EX_OK: writemsg(_("!!! Error Extracting '%s'\n") % mytbz2, noiselevel=-1) return retval #portage.locks.unlockfile(tbz2_lock) #tbz2_lock = None mylink = portage.dblink(mycat, mypkg, myroot, mysettings, vartree=vartree, treetype="bintree", blockers=blockers) retval = mylink.merge(pkgloc, infloc, myroot, myebuild, cleanup=0, mydbapi=mydbapi, prev_mtimes=prev_mtimes) did_merge_phase = True success = retval == os.EX_OK return retval finally: mysettings.pop("PORTAGE_BINPKG_FILE", None) if tbz2_lock: portage.locks.unlockfile(tbz2_lock) if True: if not did_merge_phase: # The merge phase handles this already. Callers don't know how # far this function got, so we have to call elog_process() here # so that it's only called once. from portage.elog import elog_process elog_process(mycat + "/" + mypkg, mysettings) try: if success: shutil.rmtree(builddir) except (IOError, OSError) as e: if e.errno != errno.ENOENT: raise del e