summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-11-30 00:59:48 +0000
committerZac Medico <zmedico@gentoo.org>2007-11-30 00:59:48 +0000
commit9add99f73e20f0ee9c1b40e286be45ea49a1ffa4 (patch)
tree7ff8f26d87921b542071e8f00512c77defbc87bd
parent86df9fc17e057b01d7eece3c148378d86092d4c7 (diff)
downloadportage-9add99f73e20f0ee9c1b40e286be45ea49a1ffa4.tar.gz
portage-9add99f73e20f0ee9c1b40e286be45ea49a1ffa4.tar.bz2
portage-9add99f73e20f0ee9c1b40e286be45ea49a1ffa4.zip
Bug #189417 - When ${T}/environment exists, isolate the ebuild
environment from the calling environment. This makes it possible for the build to unset a variable that was inherited from the calling environment, and the variable will remain unset between phases. (trunk r8752:8755) svn path=/main/branches/2.1.2/; revision=8756
-rwxr-xr-xbin/ebuild.sh28
-rw-r--r--bin/isolated-functions.sh2
-rw-r--r--pym/portage.py82
3 files changed, 80 insertions, 32 deletions
diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index a5b89c9d4..f8f7377d7 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -1547,32 +1547,14 @@ if hasq "depend" "${EBUILD_SH_ARGS}"; then
unset BIN_PATH BIN BODY FUNC_SRC
fi
-# Automatically try to load environment.bz2 whenever
-# "${T}/environment" does not exist, except for phases
-# such as nofetch that do not require ${T} to exist.
-if ! hasq ${EBUILD_SH_ARGS} clean depend nofetch && \
- [ ! -f "${T}/environment" ] ; then
- bzip2 -dc "${EBUILD%/*}"/environment.bz2 > \
- "${T}/environment" 2> /dev/null
- if [ $? -eq 0 ] && [ -s "${T}/environment" ] ; then
- preprocess_ebuild_env || \
- die "error processing '${EBUILD%/*}/environment.bz2'"
- else
- rm -f "${T}/environment"
- fi
-fi
-
if hasq ${EBUILD_SH_ARGS} clean ; then
true
elif ! hasq ${EBUILD_PHASE} depend && [ -f "${T}"/environment ] ; then
- if [ "${PN}" == "portage" ] && [ -n "${EBUILD_SH_ARGS}" ] ; then
- # When portage reinstalls itself, during inst/rm phases, the
- # environment may have been saved by a different version of ebuild.sh,
- # so it can't trusted that it's been properly filtered. Therefore,
- # always preprocess the environment when ${PN} == portage.
- preprocess_ebuild_env || \
- die "error processing environment"
- fi
+ # The environment may have been extracted from environment.bz2 or
+ # may have come from another version of ebuild.sh or something.
+ # In any case, preprocess it to prevent any potential interference.
+ preprocess_ebuild_env || \
+ die "error processing environment"
# Colon separated SANDBOX_* variables need to be cumulative.
for x in SANDBOX_DENY SANDBOX_READ SANDBOX_PREDICT SANDBOX_WRITE ; do
eval PORTAGE_${x}=\${!x}
diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh
index 70cae7097..62824b2bc 100644
--- a/bin/isolated-functions.sh
+++ b/bin/isolated-functions.sh
@@ -423,7 +423,7 @@ save_ebuild_env() {
EBUILD_EXIT_STATUS_FILE EBUILD_MASTER_PID \
ECLASSDIR ECLASS_DEPTH ENDCOL FAKEROOTKEY FEATURES \
GOOD HILITE HOME IMAGE \
- KV LAST_E_CMD LAST_E_LEN LD_PRELOAD MOPREFIX \
+ KV LAST_E_CMD LAST_E_LEN LD_PRELOAD MISC_FUNCTIONS_ARGS MOPREFIX \
NORMAL PATH PKGDIR PKGUSE PKG_LOGDIR PKG_TMPDIR \
PORTAGE_ACTUAL_DISTDIR PORTAGE_ARCHLIST PORTAGE_BASHRC \
PORTAGE_BINPKG_TMPFILE PORTAGE_BUILDDIR \
diff --git a/pym/portage.py b/pym/portage.py
index c1527a4d4..b3d5baf7f 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -996,6 +996,17 @@ class config:
virtuals ...etc you look in here.
"""
+ # Preserve backupenv values that are initialized in the config
+ # constructor. Also, preserve XARGS since it is set by the
+ # portage.data module.
+ _environ_whitelist = frozenset([
+ "FEATURES", "PORTAGE_BIN_PATH",
+ "PORTAGE_CONFIGROOT", "PORTAGE_DEPCACHEDIR",
+ "PORTAGE_GID", "PORTAGE_INST_GID", "PORTAGE_INST_UID",
+ "PORTAGE_PYM_PATH", "PORTDIR_OVERLAY", "ROOT", "USE_ORDER",
+ "XARGS",
+ ])
+
# Filter selected variables in the config.environ() method so that
# they don't needlessly propagate down into the ebuild environment.
_environ_filter = []
@@ -1055,6 +1066,7 @@ class config:
self.already_in_regenerate = 0
+ self._filter_calling_env = False
self.locked = 0
self.mycpv = None
self.puse = []
@@ -1081,6 +1093,7 @@ class config:
self._env_d_mtime = 0
if clone:
+ self._filter_calling_env = copy.deepcopy(clone._filter_calling_env)
self.incrementals = copy.deepcopy(clone.incrementals)
self.profile_path = copy.deepcopy(clone.profile_path)
self.user_profile_dir = copy.deepcopy(clone.user_profile_dir)
@@ -2511,6 +2524,9 @@ class config:
"return our locally-maintained environment"
mydict={}
environ_filter = self._environ_filter
+ filter_calling_env = self._filter_calling_env
+ environ_whitelist = self._environ_whitelist
+ env_d = self.configdict["env.d"]
for x in self:
if x in environ_filter:
continue
@@ -2519,6 +2535,11 @@ class config:
writemsg("!!! Non-string value in config: %s=%s\n" % \
(x, myvalue), noiselevel=-1)
continue
+ if filter_calling_env and \
+ x not in environ_whitelist:
+ if myvalue == env_d.get(x) or \
+ myvalue == os.environ.get(x):
+ continue
mydict[x] = myvalue
if not mydict.has_key("HOME") and mydict.has_key("BUILD_PREFIX"):
writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
@@ -3561,8 +3582,15 @@ def spawnebuild(mydo,actionmap,mysettings,debug,alwaysdep=0,logfile=None):
mysettings["EBUILD_PHASE"] = mydo
_doebuild_exit_status_unlink(
mysettings.get("EBUILD_EXIT_STATUS_FILE"))
- phase_retval = spawn(actionmap[mydo]["cmd"] % mydo, mysettings, debug=debug, logfile=logfile, **kwargs)
- mysettings["EBUILD_PHASE"] = ""
+ filter_calling_env_state = mysettings._filter_calling_env
+ if os.path.exists(os.path.join(mysettings["T"], "environment")):
+ mysettings._filter_calling_env = True
+ try:
+ phase_retval = spawn(actionmap[mydo]["cmd"] % mydo,
+ mysettings, debug=debug, logfile=logfile, **kwargs)
+ finally:
+ mysettings["EBUILD_PHASE"] = ""
+ mysettings._filter_calling_env = filter_calling_env_state
msg = _doebuild_exit_status_check(mydo, mysettings)
if msg:
phase_retval = 1
@@ -4163,6 +4191,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
builddir_lock = None
tmpdir = None
tmpdir_orig = None
+ filter_calling_env_state = mysettings._filter_calling_env
try:
if mydo in ("digest", "manifest", "help"):
# Temporarily exempt the depend phase from manifest checks, in case
@@ -4285,6 +4314,46 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
if logfile and not os.access(os.path.dirname(logfile), os.W_OK):
logfile = None
if have_build_dirs:
+ env_file = os.path.join(mysettings["T"], "environment")
+ env_stat = None
+ saved_env = None
+ try:
+ env_stat = os.stat(env_file)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+ del e
+ if not env_stat:
+ saved_env = os.path.join(
+ os.path.dirname(myebuild), "environment.bz2")
+ if not os.path.isfile(saved_env):
+ saved_env = None
+ if saved_env:
+ retval = os.system(
+ "bzip2 -dc '%s' > '%s'" % (saved_env, env_file))
+ try:
+ env_stat = os.stat(env_file)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+ del e
+ if os.WIFEXITED(retval) and \
+ os.WEXITSTATUS(retval) == os.EX_OK and \
+ env_stat and env_stat.st_size > 0:
+ pass
+ else:
+ writemsg("!!! Error extracting saved environment: '%s'" % \
+ saved_env, noiselevel=-1)
+ try:
+ os.unlink(env_file)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+ del e
+ env_stat = None
+ if env_stat:
+ mysettings._filter_calling_env = True
+ del env_file, env_stat, saved_env
_doebuild_exit_status_unlink(
mysettings.get("EBUILD_EXIT_STATUS_FILE"))
else:
@@ -4556,6 +4625,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
return retval
finally:
+ mysettings._filter_calling_env = filter_calling_env_state
if tmpdir:
mysettings["PORTAGE_TMPDIR"] = tmpdir_orig
shutil.rmtree(tmpdir)
@@ -9563,15 +9633,11 @@ def create_trees(config_root=None, target_root=None, trees=None):
# with ROOT != "/", so we wipe out the "backupenv" for the
# config that is associated with ROOT == "/" and regenerate
# it's incrementals.
-
# Preserve backupenv values that are initialized in the config
# constructor. Also, preserve XARGS since it is set by the
# portage.data module.
- backupenv_whitelist = set(["FEATURES", "PORTAGE_BIN_PATH",
- "PORTAGE_CONFIGROOT", "PORTAGE_DEPCACHEDIR",
- "PORTAGE_GID", "PORTAGE_INST_GID", "PORTAGE_INST_UID",
- "PORTAGE_PYM_PATH", "PORTDIR_OVERLAY", "ROOT", "USE_ORDER",
- "XARGS"])
+
+ backupenv_whitelist = settings._environ_whitelist
backupenv = settings.configdict["backupenv"]
for k, v in os.environ.iteritems():
if k in backupenv_whitelist: