summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pym/portage/dbapi/_MergeProcess.py67
-rw-r--r--pym/portage/dbapi/vartree.py61
2 files changed, 67 insertions, 61 deletions
diff --git a/pym/portage/dbapi/_MergeProcess.py b/pym/portage/dbapi/_MergeProcess.py
index 10d8873ec..43111cb16 100644
--- a/pym/portage/dbapi/_MergeProcess.py
+++ b/pym/portage/dbapi/_MergeProcess.py
@@ -1,14 +1,20 @@
# Copyright 2010-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import shutil
import signal
+import tempfile
import traceback
import errno
import fcntl
import portage
from portage import os, StringIO, _unicode_decode
+from portage.const import PORTAGE_PACKAGE_ATOM
+from portage.dep import match_from_list
import portage.elog.messages
+from portage.elog import _preload_elog_modules
+from portage.util import ensure_dirs
from _emerge.PollConstants import PollConstants
from _emerge.SpawnProcess import SpawnProcess
@@ -23,6 +29,60 @@ class MergeProcess(SpawnProcess):
'mydbapi', 'prev_mtimes', '_elog_reader_fd', '_elog_reg_id',
'_buf', '_elog_keys')
+ def _start(self):
+ self._handle_self_reinstall()
+ super(MergeProcess, self)._start()
+
+ def _handle_self_reinstall(self):
+ """
+ If portage is reinstalling itself, create temporary
+ copies of PORTAGE_BIN_PATH and PORTAGE_PYM_PATH in order
+ to avoid relying on the new versions which may be
+ incompatible. Register an atexit hook to clean up the
+ temporary directories. Pre-load elog modules here since
+ we won't be able to later if they get unmerged (happens
+ when namespace changes).
+ """
+
+ settings = self.settings
+ cpv = settings.mycpv
+ reinstall_self = False
+ if self.settings["ROOT"] == "/" and \
+ match_from_list(PORTAGE_PACKAGE_ATOM, [cpv]):
+ inherited = frozenset(self.settings.get('INHERITED', '').split())
+ if not self.vartree.dbapi.cpv_exists(cpv) or \
+ '9999' in cpv or \
+ 'git' in inherited or \
+ 'git-2' in inherited:
+ reinstall_self = True
+
+ if reinstall_self:
+ # Load lazily referenced portage submodules into memory,
+ # so imports won't fail during portage upgrade/downgrade.
+ _preload_elog_modules(self.settings)
+ portage.proxy.lazyimport._preload_portage_submodules()
+
+ # Make the temp directory inside $PORTAGE_TMPDIR/portage, since
+ # it's common for /tmp and /var/tmp to be mounted with the
+ # "noexec" option (see bug #346899).
+ build_prefix = os.path.join(settings["PORTAGE_TMPDIR"], "portage")
+ ensure_dirs(build_prefix)
+ base_path_tmp = tempfile.mkdtemp(
+ "", "._portage_reinstall_.", build_prefix)
+ portage.process.atexit_register(shutil.rmtree, base_path_tmp)
+ dir_perms = 0o755
+ for subdir in "bin", "pym":
+ var_name = "PORTAGE_%s_PATH" % subdir.upper()
+ var_orig = settings[var_name]
+ var_new = os.path.join(base_path_tmp, subdir)
+ settings[var_name] = var_new
+ settings.backup_changes(var_name)
+ shutil.copytree(var_orig, var_new, symlinks=True)
+ os.chmod(var_new, dir_perms)
+ portage._bin_path = settings['PORTAGE_BIN_PATH']
+ portage._pym_path = settings['PORTAGE_PYM_PATH']
+ os.chmod(base_path_tmp, dir_perms)
+
def _elog_output_handler(self, fd, event):
output = None
if event & PollConstants.POLLIN:
@@ -51,7 +111,6 @@ class MergeProcess(SpawnProcess):
dblink.merge().
"""
- files = self._files
elog_reader_fd, elog_writer_fd = os.pipe()
fcntl.fcntl(elog_reader_fd, fcntl.F_SETFL,
fcntl.fcntl(elog_reader_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
@@ -69,7 +128,13 @@ class MergeProcess(SpawnProcess):
self._elog_reader_fd = elog_reader_fd
self._buf = ""
self._elog_keys = set()
+
+ # invalidate relevant vardbapi caches
+ if self.vartree.dbapi._categories is not None:
+ self.vartree.dbapi._categories = None
self.vartree.dbapi._pkgs_changed = True
+ self.vartree.dbapi._clear_pkg_cache(mylink)
+
portage.process.spawned_pids.append(pid)
return [pid]
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 98f578f43..f8ce3310a 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -14,7 +14,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
'portage.dep:dep_getkey,isjustname,match_from_list,' + \
'use_reduce,_slot_re',
'portage.elog:collect_ebuild_messages,collect_messages,' + \
- 'elog_process,_merge_logentries,_preload_elog_modules',
+ 'elog_process,_merge_logentries',
'portage.locks:lockdir,unlockdir',
'portage.output:bold,colorize',
'portage.package.ebuild.doebuild:doebuild_environment,' + \
@@ -3826,65 +3826,6 @@ class dblink(object):
def merge(self, mergeroot, inforoot, myroot=None, myebuild=None, cleanup=0,
mydbapi=None, prev_mtimes=None):
"""
- If portage is reinstalling itself, create temporary
- copies of PORTAGE_BIN_PATH and PORTAGE_PYM_PATH in order
- to avoid relying on the new versions which may be
- incompatible. Register an atexit hook to clean up the
- temporary directories. Pre-load elog modules here since
- we won't be able to later if they get unmerged (happens
- when namespace changes).
-
- @param myroot: ignored, self._eroot is used instead
- """
- myroot = None
- if self.vartree.dbapi._categories is not None:
- self.vartree.dbapi._categories = None
- reinstall_self = False
- if self.myroot == "/" and \
- match_from_list(PORTAGE_PACKAGE_ATOM, [self.mycpv]):
- inherited = frozenset(self.settings.get('INHERITED', '').split())
- if not self.vartree.dbapi.cpv_exists(self.mycpv) or \
- '9999' in self.mycpv or \
- 'git' in inherited or \
- 'git-2' in inherited:
- reinstall_self = True
-
- if reinstall_self:
- # Load lazily referenced portage submodules into memory,
- # so imports won't fail during portage upgrade/downgrade.
- portage.proxy.lazyimport._preload_portage_submodules()
- settings = self.settings
-
- # Make the temp directory inside $PORTAGE_TMPDIR/portage, since
- # it's common for /tmp and /var/tmp to be mounted with the
- # "noexec" option (see bug #346899).
- build_prefix = os.path.join(settings["PORTAGE_TMPDIR"], "portage")
- ensure_dirs(build_prefix)
- base_path_tmp = tempfile.mkdtemp(
- "", "._portage_reinstall_.", build_prefix)
- portage.process.atexit_register(shutil.rmtree, base_path_tmp)
- dir_perms = 0o755
- for subdir in "bin", "pym":
- var_name = "PORTAGE_%s_PATH" % subdir.upper()
- var_orig = settings[var_name]
- var_new = os.path.join(base_path_tmp, subdir)
- settings[var_name] = var_new
- settings.backup_changes(var_name)
- shutil.copytree(var_orig, var_new, symlinks=True)
- os.chmod(var_new, dir_perms)
- portage._bin_path = settings['PORTAGE_BIN_PATH']
- portage._pym_path = settings['PORTAGE_PYM_PATH']
- os.chmod(base_path_tmp, dir_perms)
- # This serves so pre-load the modules.
- _preload_elog_modules(self.settings)
-
- return self._merge(mergeroot, inforoot,
- myebuild=myebuild, cleanup=cleanup,
- mydbapi=mydbapi, prev_mtimes=prev_mtimes)
-
- def _merge(self, mergeroot, inforoot, myroot=None, myebuild=None, cleanup=0,
- mydbapi=None, prev_mtimes=None):
- """
@param myroot: ignored, self._eroot is used instead
"""
myroot = None