From dc006a7f3b92311a054baf26f5e17069d474beaf Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Mon, 14 Jul 2008 06:38:30 +0000 Subject: * Fix doebuild so "returnpid" works for preinst and postinst. * Add async support for pkg_prerm and pkg_postrm. * Add missing "treetype" parameter to dblink constructor calls. * Fix SubProcess._wait() to check self.returncode _after_ calling the scheduler. svn path=/main/trunk/; revision=11045 --- pym/_emerge/__init__.py | 50 +++++++++++++++++++------ pym/portage/__init__.py | 88 ++++++++++++++++++++++++++++++++++---------- pym/portage/dbapi/vartree.py | 39 ++++++++++++++------ 3 files changed, 135 insertions(+), 42 deletions(-) diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index a68248a77..c02849995 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -1931,10 +1931,10 @@ class SubProcess(AsynchronousTask): self.returncode is None def _wait(self): - if self.returncode is not None: - return self.returncode if self.registered: self.scheduler.schedule(self._reg_id) + if self.returncode is not None: + return self.returncode try: wait_retval = os.waitpid(self.pid, 0) except OSError, e: @@ -2720,23 +2720,51 @@ class EbuildPhase(SubProcess): def _set_returncode(self, wait_retval): SubProcess._set_returncode(self, wait_retval) - if self.phase != "clean": - msg = portage._doebuild_exit_status_check( - self.phase, self.settings) - if msg: - self.returncode = 1 - from textwrap import wrap - from portage.elog.messages import eerror - for l in wrap(msg, 72): - eerror(l, phase=self.phase, key=self.pkg.cpv) settings = self.settings + debug = settings.get("PORTAGE_DEBUG") == "1" + log_path = settings.get("PORTAGE_LOG_FILE") + + if self.phase != "clean": + self.returncode = portage._doebuild_exit_status_check_and_log( + settings, self.phase, self.returncode) + portage._post_phase_userpriv_perms(settings) if self.phase == "install": portage._check_build_log(settings) if self.returncode == os.EX_OK: self.returncode = portage._post_src_install_checks(settings) + elif self.phase == "preinst": + + if self.returncode == os.EX_OK: + portage._doebuild_exit_status_unlink( + settings.get("EBUILD_EXIT_STATUS_FILE")) + phase_retval = portage.spawn( + " ".join(portage._post_pkg_preinst_cmd(settings)), + settings, debug=debug, free=1, logfile=log_path) + phase_retval = portage._doebuild_exit_status_check_and_log( + settings, self.phase, phase_retval) + if phase_retval != os.EX_OK: + writemsg("!!! post preinst failed; exiting.\n", + noiselevel=-1) + self.returncode = phase_retval + + elif self.phase == "postinst": + + if self.returncode == os.EX_OK: + portage._doebuild_exit_status_unlink( + settings.get("EBUILD_EXIT_STATUS_FILE")) + phase_retval = portage.spawn( + " ".join(portage._post_pkg_postinst_cmd(settings)), + settings, debug=debug, free=1, logfile=log_path) + phase_retval = portage._doebuild_exit_status_check_and_log( + settings, self.phase, phase_retval) + if phase_retval != os.EX_OK: + writemsg("!!! post postinst failed; exiting.\n", + noiselevel=-1) + self.returncode = phase_retval + class EbuildBinpkg(EbuildPhase): """ This assumes that src_install() has successfully completed. diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index fd4d14b2f..c9586c19a 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -4380,6 +4380,42 @@ def _post_src_install_uid_fix(mysettings): mode=mystat.st_mode, stat_cached=mystat, follow_links=False) +def _post_pkg_preinst_cmd(mysettings): + """ + Post phase logic and tasks that have been factored out of + ebuild.sh. Call preinst_mask last so that INSTALL_MASK can + can be used to wipe out any gmon.out files created during + previous functions (in case any tools were built with -pg + in CFLAGS). + """ + + portage_bin_path = mysettings["PORTAGE_BIN_PATH"] + misc_sh_binary = os.path.join(portage_bin_path, + os.path.basename(MISC_SH_BINARY)) + + mysettings["EBUILD_PHASE"] = "" + myargs = [_shell_quote(misc_sh_binary), + "preinst_bsdflags", + "preinst_sfperms", "preinst_selinux_labels", + "preinst_suid_scan", "preinst_mask"] + + return myargs + +def _post_pkg_postinst_cmd(mysettings): + """ + Post phase logic and tasks that have been factored out of + build.sh. + """ + + portage_bin_path = mysettings["PORTAGE_BIN_PATH"] + misc_sh_binary = os.path.join(portage_bin_path, + os.path.basename(MISC_SH_BINARY)) + + mysettings["EBUILD_PHASE"] = "" + myargs = [_shell_quote(misc_sh_binary), "postinst_bsdflags"] + + return myargs + def _spawn_misc_sh(mysettings, commands, **kwargs): """ @param mysettings: the ebuild config @@ -4822,6 +4858,18 @@ def _doebuild_exit_status_check(mydo, settings): "errors (bug #200313)." return msg +def _doebuild_exit_status_check_and_log(settings, mydo, retval): + if retval != os.EX_OK: + return retval + msg = _doebuild_exit_status_check(mydo, settings) + if msg: + retval = 1 + from textwrap import wrap + from portage.elog.messages import eerror + for l in wrap(msg, 72): + eerror(l, phase=mydo, key=settings.mycpv) + return retval + def _doebuild_exit_status_unlink(exit_status_file): """ Double check to make sure it really doesn't exist @@ -5277,22 +5325,18 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, elif mydo == "preinst": phase_retval = spawn( _shell_quote(ebuild_sh_binary) + " " + mydo, - mysettings, debug=debug, free=1, logfile=logfile) + mysettings, debug=debug, free=1, logfile=logfile, + fd_pipes=fd_pipes, returnpid=returnpid) + + if returnpid: + return phase_retval + phase_retval = exit_status_check(phase_retval) if phase_retval == os.EX_OK: - # Post phase logic and tasks that have been factored out of - # ebuild.sh. Call preinst_mask last so that INSTALL_MASK can - # can be used to wipe out any gmon.out files created during - # previous functions (in case any tools were built with -pg - # in CFLAGS). - myargs = [_shell_quote(misc_sh_binary), - "preinst_bsdflags", - "preinst_sfperms", "preinst_selinux_labels", - "preinst_suid_scan", "preinst_mask"] _doebuild_exit_status_unlink( mysettings.get("EBUILD_EXIT_STATUS_FILE")) - mysettings["EBUILD_PHASE"] = "" - phase_retval = spawn(" ".join(myargs), + phase_retval = spawn( + " ".join(_post_pkg_preinst_cmd(mysettings)), mysettings, debug=debug, free=1, logfile=logfile) phase_retval = exit_status_check(phase_retval) if phase_retval != os.EX_OK: @@ -5302,16 +5346,17 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, elif mydo == "postinst": phase_retval = spawn( _shell_quote(ebuild_sh_binary) + " " + mydo, - mysettings, debug=debug, free=1, logfile=logfile) + mysettings, debug=debug, free=1, logfile=logfile, + fd_pipes=fd_pipes, returnpid=returnpid) + + if returnpid: + return phase_retval + phase_retval = exit_status_check(phase_retval) if phase_retval == os.EX_OK: - # Post phase logic and tasks that have been factored out of - # ebuild.sh. - myargs = [_shell_quote(misc_sh_binary), "postinst_bsdflags"] _doebuild_exit_status_unlink( mysettings.get("EBUILD_EXIT_STATUS_FILE")) - mysettings["EBUILD_PHASE"] = "" - phase_retval = spawn(" ".join(myargs), + phase_retval = spawn(" ".join(_post_pkg_postinst_cmd(mysettings)), mysettings, debug=debug, free=1, logfile=logfile) phase_retval = exit_status_check(phase_retval) if phase_retval != os.EX_OK: @@ -5321,7 +5366,12 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, elif mydo in ("prerm", "postrm", "config", "info"): retval = spawn( _shell_quote(ebuild_sh_binary) + " " + mydo, - mysettings, debug=debug, free=1, logfile=logfile) + mysettings, debug=debug, free=1, logfile=logfile, + fd_pipes=fd_pipes, returnpid=returnpid) + + if returnpid: + return retval + retval = exit_status_check(retval) return retval diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index fdb16a225..1dfa8946a 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -895,7 +895,7 @@ class vardbapi(dbapi): def _dblink(self, cpv): category, pf = catsplit(cpv) return dblink(category, pf, self.root, - self.settings, vartree=self.vartree) + self.settings, vartree=self.vartree, treetype="vartree") def removeFromContents(self, pkg, paths, relative_paths=True): """ @@ -1523,7 +1523,9 @@ class dblink(object): if cur_cpv == self.mycpv: continue others_in_slot.append(dblink(self.cat, catsplit(cur_cpv)[1], - self.vartree.root, self.settings, vartree=self.vartree)) + self.vartree.root, self.settings, vartree=self.vartree, + treetype="vartree")) + retval = self._security_check([self] + others_in_slot) if retval: return retval @@ -1560,6 +1562,7 @@ class dblink(object): uid=portage_uid, gid=portage_gid, mode=070, mask=0) builddir_lock = None catdir_lock = None + scheduler = self._scheduler retval = -1 try: if myebuildpath: @@ -1573,11 +1576,16 @@ class dblink(object): unlockdir(catdir_lock) finally: catdir_lock = None - # Eventually, we'd like to pass in the saved ebuild env here... - retval = doebuild(myebuildpath, "prerm", self.myroot, - self.settings, cleanup=cleanup, use_cache=0, - mydbapi=self.vartree.dbapi, tree="vartree", - vartree=self.vartree) + + if scheduler is None: + retval = doebuild(myebuildpath, ebuild_phase, self.myroot, + self.settings, cleanup=cleanup, use_cache=0, + mydbapi=self.vartree.dbapi, tree=self.treetype, + vartree=self.vartree) + else: + retval = scheduler.dblinkEbuildPhase( + self, self.vartree.dbapi, myebuildpath, ebuild_phase) + # XXX: Decide how to handle failures here. if retval != os.EX_OK: writemsg("!!! FAILED prerm: %s\n" % retval, noiselevel=-1) @@ -1592,9 +1600,13 @@ class dblink(object): if myebuildpath: ebuild_phase = "postrm" - retval = doebuild(myebuildpath, "postrm", self.myroot, - self.settings, use_cache=0, tree="vartree", - mydbapi=self.vartree.dbapi, vartree=self.vartree) + if scheduler is None: + retval = doebuild(myebuildpath, ebuild_phase, self.myroot, + self.settings, use_cache=0, tree=self.treetype, + mydbapi=self.vartree.dbapi, vartree=self.vartree) + else: + retval = scheduler.dblinkEbuildPhase( + self, self.vartree.dbapi, myebuildpath, ebuild_phase) # XXX: Decide how to handle failures here. if retval != os.EX_OK: @@ -1751,7 +1763,8 @@ class dblink(object): continue others_in_slot.append(dblink(self.cat, catsplit(cur_cpv)[1], self.vartree.root, self.settings, - vartree=self.vartree)) + vartree=self.vartree, treetype="vartree")) + dest_root = normalize_path(self.vartree.root).rstrip(os.path.sep) + \ os.path.sep dest_root_len = len(dest_root) - 1 @@ -2380,7 +2393,9 @@ class dblink(object): # we need it to have private ${T} etc... for things like elog. others_in_slot.append(dblink(self.cat, catsplit(cur_cpv)[1], self.vartree.root, config(clone=self.settings), - vartree=self.vartree, scheduler=self._scheduler)) + vartree=self.vartree, treetype="vartree", + scheduler=self._scheduler)) + retval = self._security_check(others_in_slot) if retval: return retval -- cgit v1.2.3-1-g7c22