1
2
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
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
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
34
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
48
49
50
51
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
62
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
95
98
111