x user interface for preserve-libs FEATURE (genone, fuzzyray?)
x resolve the eselect-news situation (genone)
- package set documentation (genone)
+- repository configuration file and `emerge --sync [repo_set]... [repo]...`
+ support for overlays and binhosts (zmedico)
(- denotes open/incomplete tasks, x denotes completed tasks)
# interfering with the current environment. This is useful when an existing
# environment needs to be loaded from a binary or installed package.
preprocess_ebuild_env() {
- filter_readonly_variables --filter-sandbox < "${T}"/environment \
- > "${T}"/environment.filtered
- if [ $? -ne 0 ] ; then
- rm -f "${T}/environment.filtered"
- return 1
- fi
+ local filter_opts=""
+ if [ -f "${T}/environment.raw" ] ; then
+ # This is a signal from the python side, indicating that the
+ # environment may contain stale SANDBOX_{DENY,PREDICT,READ,WRITE}
+ # variables that should be filtered out. Between phases, these
+ # variables are normally preserved.
+ filter_opts="--filter-sandbox ${filter_opts}"
+ fi
+ filter_readonly_variables ${filter_opts} < "${T}"/environment \
+ > "${T}"/environment.filtered || return $?
+ unset filter_opts
mv "${T}"/environment.filtered "${T}"/environment || return $?
rm -f "${T}/environment.success" || return $?
# WARNING: Code inside this subshell should avoid making assumptions
save_ebuild_env || exit $?
touch "${T}/environment.success" || exit $?
) | filter_readonly_variables > "${T}/environment.filtered"
+ local retval
if [ -e "${T}/environment.success" ] ; then
- rm "${T}/environment.success"
mv "${T}/environment.filtered" "${T}/environment"
- return $?
+ retval=$?
else
- rm -f "${T}/environment.filtered"
+ retval=1
fi
- return 1
+ rm -f "${T}"/environment.{filtered,raw,success}
+ return ${retval}
}
# === === === === === === === === === === === === === === === === === ===
9>&-
fi
set +f
- [ -n "${EBUILD_EXIT_STATUS_FILE}" ] && \
- touch "${EBUILD_EXIT_STATUS_FILE}" &>/dev/null
- exit 0
;;
*)
export SANDBOX_ON="1"
fi
}
-get_utc_from_string() {
+get_utc_second_from_string() {
local s="$1"
-
- seconds=$(date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s")
+ date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s"
}
get_portage_timestamp() {
have_files=0
fi
else
- utc_date=$(get_utc_from_string "${date}")
+ local utc_seconds=$(get_utc_second_from_string "${date}")
#
# Check that this snapshot
# is what it claims to be...
#
- if [ ${snapshot_timestamp} -lt ${seconds} ] || \
- [ ${snapshot_timestamp} -gt $((${seconds}+ 2*86400)) ]; then
+ if [ ${snapshot_timestamp} -lt ${utc_seconds} ] || \
+ [ ${snapshot_timestamp} -gt $((${utc_seconds}+ 2*86400)) ]; then
echo "Warning: Snapshot timestamp is not in acceptable period."
have_files=0
directory = @DOMAIN_PREFIX@/etc/portage/sets
# Set to rebuild all packages that need a preserved lib that only remains due
-# to FEATURES=preserved-libs
+# to FEATURES=preserve-libs
[preserved-rebuild]
-class = portage.sets.dbapi.PreservedConsumerSet
+class = portage.sets.dbapi.PreservedLibraryConsumerSet
if repo_name_prev:
repo_path_prev = portdb.getRepositoryPath(
repo_name_prev)
- # To avoid spam during the transition period, don't
- # show ? if the installed package is missing a
- # repository label.
- if not repo_path_prev or \
- repo_path_prev == repo_path_real:
+ if repo_path_prev == repo_path_real:
repoadd = repo_display.repoStr(repo_path_real)
else:
repoadd = "%s=>%s" % (
if myaction in ("clean", "config", "depclean", "info", "prune", "unmerge", None):
root_config = trees[settings["ROOT"]]["root_config"]
setconfig = root_config.setconfig
- sets = root_config.sets
+ sets = setconfig.getSets()
# emerge relies on the existance of sets with names "world" and "system"
- for s in ("world", "system"):
+ required_sets = ("world", "system")
+ for s in required_sets:
if s not in sets:
- print "emerge: incomplete set configuration, no \"%s\" set defined" % s
- print " sets defined: %s" % ", ".join(sets)
+ msg = ["emerge: incomplete set configuration, " + \
+ "no \"%s\" set defined" % s]
+ msg.append(" sets defined: %s" % ", ".join(sets))
+ for line in msg:
+ sys.stderr.write(line + "\n")
return 1
+ unmerge_actions = ("unmerge", "prune", "clean", "depclean")
+ # In order to know exactly which atoms/sets should be added to the
+ # world file, the depgraph performs set expansion later. It will get
+ # confused about where the atoms came from if it's not allowed to
+ # expand them itself.
+ do_not_expand = (None, )
newargs = []
for a in myfiles:
if a in ("system", "world"):
print "emerge: there are no sets to satisfy %s." % \
colorize("INFORM", s)
return 1
- if myaction in ["unmerge", "prune", "clean", "depclean"] and \
+ if myaction in unmerge_actions and \
not sets[s].supportsOperation("unmerge"):
- print "emerge: the given set %s does not support unmerge operations" % s
+ sys.stderr.write("emerge: the given set %s does " + \
+ "not support unmerge operations\n" % s)
return 1
if not setconfig.getSetAtoms(s):
print "emerge: '%s' is an empty set" % s
- elif myaction != None:
+ elif myaction not in do_not_expand:
newargs.extend(setconfig.getSetAtoms(s))
else:
newargs.append(SETPREFIX+s)
_environ_whitelist = []
- # Preserve backupenv values that are initialized in the config
- # constructor. Also, preserve XARGS since it is set by the
- # portage.data module.
+ # Whitelisted variables are always allowed to enter the ebuild
+ # environment. Generally, this only includes special portage
+ # variables. Ebuilds can unset variables that are not whitelisted
+ # and rely on them remaining unset for future phases, without them
+ # leaking back in from various locations (bug #189417). It's very
+ # important to set our special BASH_ENV variable in the ebuild
+ # environment in order to prevent sandbox from sourcing /etc/profile
+ # in it's bashrc (causing major leakage).
_environ_whitelist += [
- "DISTDIR", "FEATURES", "PORTAGE_BIN_PATH",
- "PORTAGE_CONFIGROOT", "PORTAGE_DEPCACHEDIR",
+ "BASH_ENV", "BUILD_PREFIX", "D",
+ "DISTDIR", "DOC_SYMLINKS_DIR", "EBUILD_EXIT_STATUS_FILE",
+ "EBUILD", "EBUILD_PHASE", "ECLASSDIR", "ECLASS_DEPTH", "EMERGE_FROM",
+ "FEATURES", "FILESDIR", "HOME", "PATH",
+ "PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR",
+ "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST",
+ "PORTAGE_BASHRC", "PORTAGE_BINPKG_TMPFILE", "PORTAGE_BIN_PATH",
+ "PORTAGE_BUILDDIR", "PORTAGE_COLORMAP",
+ "PORTAGE_CONFIGROOT", "PORTAGE_DEBUG", "PORTAGE_DEPCACHEDIR",
"PORTAGE_GID", "PORTAGE_INST_GID", "PORTAGE_INST_UID",
- "PORTAGE_PYM_PATH", "PORTAGE_WORKDIR_MODE",
- "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH",
- "ROOT", "ROOTPATH", "USE_ORDER",
+ "PORTAGE_LOG_FILE", "PORTAGE_MASTER_PID",
+ "PORTAGE_PYM_PATH", "PORTAGE_REPO_NAME", "PORTAGE_RESTRICT",
+ "PORTAGE_TMPDIR", "PORTAGE_WORKDIR_MODE",
+ "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", "PROFILE_PATHS",
+ "ROOT", "ROOTPATH", "STARTDIR", "T", "TMP", "TMPDIR",
+ "USE_EXPAND", "USE_ORDER", "WORKDIR",
"XARGS",
]
+ _environ_whitelist += [
+ "A", "AA", "CATEGORY", "P", "PF", "PN", "PR", "PV", "PVR"
+ ]
+
# misc variables inherited from the calling environment
_environ_whitelist += [
"COLORTERM", "DISPLAY", "EDITOR", "LESS",
if filter_calling_env and \
x not in environ_whitelist and \
not self._environ_whitelist_re.match(x):
- if myvalue == env_d.get(x) or \
- myvalue == os.environ.get(x):
- continue
+ # Do not allow anything to leak into the ebuild
+ # environment unless it is explicitly whitelisted.
+ # This ensures that variables unset by the ebuild
+ # remain unset.
+ 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")
os.path.basename(MISC_SH_BINARY))
mycommand = " ".join([_shell_quote(misc_sh_binary),
"install_qa_check", "install_symlink_html_docs"])
- qa_retval = spawn(mycommand, mysettings, debug=debug, logfile=logfile, **kwargs)
+ filter_calling_env_state = mysettings._filter_calling_env
+ if os.path.exists(os.path.join(mysettings["T"], "environment")):
+ mysettings._filter_calling_env = True
+ try:
+ qa_retval = spawn(mycommand, mysettings, debug=debug,
+ logfile=logfile, **kwargs)
+ finally:
+ mysettings._filter_calling_env = filter_calling_env_state
if qa_retval:
writemsg("!!! install_qa_check failed; exiting.\n",
noiselevel=-1)
if os.WIFEXITED(retval) and \
os.WEXITSTATUS(retval) == os.EX_OK and \
env_stat and env_stat.st_size > 0:
- pass
+ # This is a signal to ebuild.sh, so that it knows to filter
+ # out things like SANDBOX_{DENY,PREDICT,READ,WRITE} that
+ # would be preserved between normal phases.
+ open(env_file + ".raw", "w")
else:
writemsg(("!!! Error extracting saved " + \
"environment: '%s'\n") % \
def getSets(self):
self._parse()
- return self.psets
+ return self.psets.copy()
def getSetAtoms(self, setname, ignorelist=None):
myset = self.getSets()[setname]