Package _emerge :: Module PackageUninstall
[hide private]

Source Code for Module _emerge.PackageUninstall

  1  # Copyright 1999-2012 Gentoo Foundation 
  2  # Distributed under the terms of the GNU General Public License v2 
  3   
  4  import logging 
  5  import portage 
  6  from portage import os 
  7  from portage.dbapi._MergeProcess import MergeProcess 
  8  from portage.exception import UnsupportedAPIException 
  9  from _emerge.EbuildBuildDir import EbuildBuildDir 
 10  from _emerge.emergelog import emergelog 
 11  from _emerge.CompositeTask import CompositeTask 
 12  from _emerge.unmerge import _unmerge_display 
 13   
14 -class PackageUninstall(CompositeTask):
15 """ 16 Uninstall a package asynchronously in a subprocess. When 17 both parallel-install and ebuild-locks FEATURES are enabled, 18 it is essential for the ebuild-locks code to execute in a 19 subprocess, since the portage.locks module does not behave 20 as desired if we try to lock the same file multiple times 21 concurrently from the same process for ebuild-locks phases 22 such as pkg_setup, pkg_prerm, and pkg_postrm. 23 """ 24 25 __slots__ = ("world_atom", "ldpath_mtimes", "opts", 26 "pkg", "settings", "_builddir_lock") 27
28 - def _start(self):
29 30 vardb = self.pkg.root_config.trees["vartree"].dbapi 31 dbdir = vardb.getpath(self.pkg.cpv) 32 if not os.path.exists(dbdir): 33 # Apparently the package got uninstalled 34 # already, so we can safely return early. 35 self.returncode = os.EX_OK 36 self._async_wait() 37 return 38 39 self.settings.setcpv(self.pkg) 40 cat, pf = portage.catsplit(self.pkg.cpv) 41 myebuildpath = os.path.join(dbdir, pf + ".ebuild") 42 43 try: 44 portage.doebuild_environment(myebuildpath, "prerm", 45 settings=self.settings, db=vardb) 46 except UnsupportedAPIException: 47 # This is safe to ignore since this function is 48 # guaranteed to set PORTAGE_BUILDDIR even though 49 # it raises UnsupportedAPIException. The error 50 # will be logged when it prevents the pkg_prerm 51 # and pkg_postrm phases from executing. 52 pass 53 54 self._builddir_lock = EbuildBuildDir( 55 scheduler=self.scheduler, settings=self.settings) 56 self._builddir_lock.lock() 57 58 portage.prepare_build_dirs( 59 settings=self.settings, cleanup=True) 60 61 # Output only gets logged if it comes after prepare_build_dirs() 62 # which initializes PORTAGE_LOG_FILE. 63 retval, pkgmap = _unmerge_display(self.pkg.root_config, 64 self.opts, "unmerge", [self.pkg.cpv], clean_delay=0, 65 writemsg_level=self._writemsg_level) 66 67 if retval != os.EX_OK: 68 self._builddir_lock.unlock() 69 self.returncode = retval 70 self._async_wait() 71 return 72 73 self._writemsg_level(">>> Unmerging %s...\n" % (self.pkg.cpv,), 74 noiselevel=-1) 75 self._emergelog("=== Unmerging... (%s)" % (self.pkg.cpv,)) 76 77 unmerge_task = MergeProcess( 78 mycat=cat, mypkg=pf, settings=self.settings, 79 treetype="vartree", vartree=self.pkg.root_config.trees["vartree"], 80 scheduler=self.scheduler, background=self.background, 81 mydbapi=self.pkg.root_config.trees["vartree"].dbapi, 82 prev_mtimes=self.ldpath_mtimes, 83 logfile=self.settings.get("PORTAGE_LOG_FILE"), unmerge=True) 84 85 self._start_task(unmerge_task, self._unmerge_exit)
86
87 - def _unmerge_exit(self, unmerge_task):
88 if self._final_exit(unmerge_task) != os.EX_OK: 89 self._emergelog(" !!! unmerge FAILURE: %s" % (self.pkg.cpv,)) 90 else: 91 self._emergelog(" >>> unmerge success: %s" % (self.pkg.cpv,)) 92 self.world_atom(self.pkg) 93 self._builddir_lock.unlock() 94 self.wait()
95
96 - def _emergelog(self, msg):
97 emergelog("notitles" not in self.settings.features, msg)
98
99 - def _writemsg_level(self, msg, level=0, noiselevel=0):
100 101 log_path = self.settings.get("PORTAGE_LOG_FILE") 102 background = self.background 103 104 if log_path is None: 105 if not (background and level < logging.WARNING): 106 portage.util.writemsg_level(msg, 107 level=level, noiselevel=noiselevel) 108 else: 109 self.scheduler.output(msg, log_path=log_path, 110 level=level, noiselevel=noiselevel)
111