portage-2.1.5
==================================
+* The pkg_postinst phase is now called after the previous version of a
+ package has been removed. As a consequence, it is no longer possible
+ to call has_version in pkg_postinst to detect whether the current
+ install operation is an upgrade or downgrade. If this information is
+ needed during the pkg_postinst phase, do the has_version call in an
+ earlier phase (such as pkg_preinst) and store the result in a global
+ variable to be accessed by pkg_postinst when it is called. Bug #226505
+ tracks all issues related to this phase execution order change.
+
* Blockers are now resolved automatically in many more cases
than before. When it's safe, blocked packages are uninstalled
automatically so that users are no longer inconvenienced with the
local messagetype
[ -z "${1}" -o -z "${T}" -o ! -d "${T}/logging" ] && return 1
case "${1}" in
- INFO|WARN|ERROR|LOG|QA)
+ BLANK|INFO|WARN|ERROR|LOG|QA)
messagetype="${1}"
shift
;;
return 0
}
+eblank() {
+ [[ ${LAST_E_CMD} == "eblank" ]] && return 0
+ elog_base BLANK
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ echo -e " ${BLANK}*${NORMAL}"
+ LAST_E_CMD="eblank"
+ return 0
+}
+
eqawarn() {
elog_base QA "$*"
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
vecho -e " ${WARN}*${NORMAL} $*" >&2
+ LAST_E_CMD="eqawarn"
return 0
}
elog() {
elog_base LOG "$*"
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -e " ${GOOD}*${NORMAL} $*"
+ LAST_E_CMD="elog"
return 0
}
_eend ${retval} eerror "$*"
+ LAST_E_CMD="eend"
return ${retval}
}
COLS="25 80"
ENDCOL=
+ BLANK=
GOOD=
WARN=
BAD=
if [ -n "${PORTAGE_COLORMAP}" ] ; then
eval ${PORTAGE_COLORMAP}
else
+ BLANK=$'\e[37m'
GOOD=$'\e[32;01m'
WARN=$'\e[33;01m'
BAD=$'\e[31;01m'
# logging related variables:
# PORTAGE_ELOG_CLASSES: selects messages to be logged, possible values are:
-# info, warn, error, log, qa, *
+# blank, info, warn, error, log, qa, *
# Warning: commenting this will disable elog
-PORTAGE_ELOG_CLASSES="warn error log"
+PORTAGE_ELOG_CLASSES="blank log warn error"
# PORTAGE_ELOG_SYSTEM: selects the module(s) to process the log messages. Modules
# included in portage are (empty means logging is disabled):
PORTAGE_WORKDIR_MODE="0700"
# Some defaults for elog
-PORTAGE_ELOG_CLASSES="log warn error"
+PORTAGE_ELOG_CLASSES="blank log warn error"
PORTAGE_ELOG_SYSTEM="save_summary echo"
PORTAGE_ELOG_MAILURI="@rootuser@"
<chapter id='package-ebuild'>
<title>Ebuild</title>
&package_ebuild_phases;
+&package_ebuild_helper_functions;
</chapter>
--- /dev/null
+<sect1 id='package-ebuild-helper-functions'>
+ <title>Helper Functions</title>
+ <sect2 id='package-ebuild-helper-functions-output'>
+ <title>Output</title>
+ <sect3 id='package-ebuild-helper-functions-output-ebegin'>
+ <title>ebegin</title>
+ <para>
+ Like einfo, we output a helpful message and then hint that the following
+ operation may take some time to complete. Once the task is finished, you
+ need to call eend.
+ </para>
+ </sect3>
+ <sect3 id='package-ebuild-helper-functions-output-eblank'>
+ <title>eblank</title>
+ <para>
+ Show a blank line. Consecutive eblank calls collapse into
+ a single blank line.
+ </para>
+ </sect3>
+ <sect3 id='package-ebuild-helper-functions-output-eend'>
+ <title>eend</title>
+ <para>
+ Followup the ebegin message with an appropriate "OK" or "!!" (for errors)
+ marker. If status is non-zero, then the additional error message is
+ displayed.
+ </para>
+ </sect3>
+ <sect3 id='package-ebuild-helper-functions-output-einfo'>
+ <title>einfo</title>
+ <para>
+ Same as elog, but should be used when the message isn't important
+ to the user (like progress or status messages during the build process).
+ </para>
+ </sect3>
+ <sect3 id='package-ebuild-helper-functions-output-elog'>
+ <title>elog</title>
+ <para>
+ If you need to display a message that you wish the user to read
+ and take notice of, then use elog. It works just like echo(1),
+ but adds a little more to the output so as to catch the user's eye.
+ The message will also be logged by portage for later review.
+ </para>
+ </sect3>
+ <sect3 id='package-ebuild-helper-functions-output-eqawarn'>
+ <title>eqawarn</title>
+ <para>
+ Same as einfo, but should be used when showing a QA warning to the user.
+ </para>
+ </sect3>
+ <sect3 id='package-ebuild-helper-functions-output-ewarn'>
+ <title>ewarn</title>
+ <para>
+ Same as einfo, but should be used when showing a warning to the user.
+ </para>
+ </sect3>
+ </sect2>
+</sect1>
</listitem>
</itemizedlist>
</para>
+ <sect2 id='package-ebuild-phases-previous-installed'>
+ <title>Interaction with previous installed version</title>
+ <para>
+ The order for upgrade and downgrade operations changed in
+ version 2.1.5, but the order for reinstall operations remained unchanged.
+ </para>
+ <sect3 id='package-ebuild-phases-before-2.1.5'>
+ <title>Upgrade/downgrade order used by versions less than 2.1.5 (deprecated)</title>
+ <para>
+ <itemizedlist>
+ <listitem>
+ pkg_preinst
+ </listitem>
+ <listitem>
+ pkg_postinst
+ </listitem>
+ <listitem>
+ pkg_prerm
+ </listitem>
+ <listitem>
+ pkg_postrm
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect3>
+ <sect3 id='package-ebuild-phases-after-2.1.5'>
+ <title>Upgrade/downgrade order starting with version 2.1.5</title>
+ <para>
+ The new order for upgrades and downgrades is identical to the order used
+ for reinstall operations:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ pkg_preinst
+ </listitem>
+ <listitem>
+ pkg_prerm
+ </listitem>
+ <listitem>
+ pkg_postrm
+ </listitem>
+ <listitem>
+ pkg_postinst
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Now that pkg_postinst is called after all other phases, it's not possible to
+ call has_version in pkg_postinst to detect whether the current install
+ operation is an upgrade or downgrade. If this information is needed during the
+ pkg_postinst phase, do the has_version call in an earlier phase (such as
+ pkg_preinst) and store the result in a global variable to be accessed by
+ pkg_postinst when it is called.
+ </para>
+ </sect3>
+ </sect2>
</sect1>
<!ENTITY package SYSTEM "package.docbook">
<!ENTITY package_ebuild SYSTEM "package/ebuild.docbook">
<!ENTITY package_ebuild_phases SYSTEM "package/ebuild/phases.docbook">
+ <!ENTITY package_ebuild_helper_functions SYSTEM "package/ebuild/helper_functions.docbook">
<!ENTITY qa SYSTEM "qa.docbook">
<!ENTITY config SYSTEM "config.docbook">
<!ENTITY config_bashrc SYSTEM "config/bashrc.docbook">
\fBBAD\fR = \fI"red"\fR
Defines color used for some words occuring in bad context.
.TP
+\fBBLANK\fR = \fI"lightgray"\fR
+Defines color used to display eblank lines.
+.TP
\fBBRACKET\fR = \fI"blue"\fR
Defines color used for brackets.
.TP
.RE
.SH "HELPER FUNCTIONS: OUTPUT"
.TP
+\fBeblank\fR
+Show a blank line. Consecutive eblank calls collapse into
+a single blank line.
+.TP
\fBeinfo\fR \fI"disposable message"\fR
Same as \fBelog\fR, but should be used when the message isn't important to the
user (like progress or status messages during the build process).
\fBewarn\fR \fI"warning message"\fR
Same as \fBeinfo\fR, but should be used when showing a warning to the user.
.TP
+\fBeqawarn\fR \fI"QA warning message"\fR
+Same as \fBeinfo\fR, but should be used when showing a QA warning to the user.
+.TP
\fBeerror\fR \fI"error message"\fR
Same as \fBeinfo\fR, but should be used when showing an error to the user.
.TP
\fI/usr/portage/profiles\fR.
.TP
.BR CHOST
-The \CHOST\fR variable in \fBmake.conf\fR(5) is used to mask binary packages
-that have been built with a different \CHOST\fR setting. The only
-way to unmask such a binary package is to change the \CHOST\fR environment
-variable so that it exactly matches that of the binary package.
+Use the \fBACCEPT_CHOSTS\fR variable in \fBmake.conf\fR(5) to control
+\fBCHOST\fR acceptance for binary packages.
.TP
.BR EAPI
The \fBEAPI\fR variable in an \fBebuild\fR(5) file is used to mask packages
export USE="\-*"
.SH "VARIABLES"
.TP
+\fBACCEPT_CHOSTS\fR = \fI[space delimited list of CHOST values]\fR
+Specifies acceptable \fBCHOST\fR values for binary packages. Regular
+expression syntax is supported, so it is necessary to escape
+\fBCHOST\fR characters if they have special meaning in regular expressions.
+.br
+Defaults to the value of $CHOST.
+.TP
\fBACCEPT_KEYWORDS\fR = \fI[space delimited list of KEYWORDS]\fR
Enable testing of ebuilds that have not yet been deemed 'stable'. Users
of the 'x86' architecture would set this to '~x86' while ppc users would
vdb_lock = portage.locks.lockdir(vdb_path)
real_dbapi = real_vartree.dbapi
slot_counters = {}
- for cpv in real_dbapi.cpv_all(use_cache=0):
+ for cpv in real_dbapi.cpv_all():
cache_key = ("installed", self.root, cpv, "nomerge")
pkg = self._pkg_cache.get(cache_key)
if pkg is not None:
if inforoot=='':
continue
- if not os.path.isdir(inforoot):
+ if not os.path.isdir(inforoot) or \
+ not os.access(inforoot, os.W_OK):
continue
errmsg = ""
file_list = os.listdir(inforoot)
vdb_path = os.path.join(target_root, portage.VDB_PATH)
portage.util.ensure_dirs(vdb_path)
- vdb_lock = portage.locks.lockdir(vdb_path)
- try:
- if "noinfo" not in settings.features:
- chk_updated_info_files(target_root + EPREFIX, infodirs, info_mtimes, retval)
- mtimedb.commit()
- finally:
- portage.locks.unlockdir(vdb_lock)
+ vdb_lock = None
+ if os.access(vdb_path, os.W_OK):
+ vdb_lock = portage.locks.lockdir(vdb_path)
+
+ if vdb_lock:
+ try:
+ if "noinfo" not in settings.features:
+ chk_updated_info_files(target_root, EPREFIX_LSTRIP
+ infodirs, info_mtimes, retval)
+ mtimedb.commit()
+ finally:
+ if vdb_lock:
+ portage.locks.unlockdir(vdb_lock)
- chk_updated_cfg_files(target_root + EPREFIX, config_protect)
+ chk_updated_cfg_files(target_root, EPREFIX_LSTRIP, config_protect)
display_news_notification(trees)
setconfig.active.append(s)
if myaction in unmerge_actions and \
not sets[s].supportsOperation("unmerge"):
- sys.stderr.write("emerge: the given set %s does " + \
- "not support unmerge operations\n" % s)
+ sys.stderr.write("emerge: the given set '%s' does " % s + \
+ "not support unmerge operations\n")
return 1
if not setconfig.getSetAtoms(s):
print "emerge: '%s' is an empty set" % s
]
_environ_filter = frozenset(_environ_filter)
- _accept_chost_re = None
def __init__(self, clone=None, mycpv=None, config_profile_path=None,
config_incrementals=None, config_root=None, target_root=None,
self.puse = []
self.modifiedkeys = []
self.uvlist = []
+ self._accept_chost_re = None
self.virtuals = {}
self.virts_p = {}
if not accept_chost:
self._accept_chost_re = re.compile(".*")
elif len(accept_chost) == 1:
- self._accept_chost_re = re.compile(accept_chost[0])
+ self._accept_chost_re = re.compile(r'^%s$' % accept_chost[0])
else:
self._accept_chost_re = re.compile(
r'^(%s)$' % "|".join(accept_chost))
# Allow color.map to control colors associated with einfo, ewarn, etc...
mycolors = []
- for c in ("GOOD", "WARN", "BAD", "HILITE", "BRACKET"):
+ for c in ("BLANK", "GOOD", "WARN", "BAD", "HILITE", "BRACKET"):
mycolors.append("%s=$'%s'" % (c, portage.output.codes[c]))
mysettings["PORTAGE_COLORMAP"] = "\n".join(mycolors)
libs = {}
obj_properties = {}
lines = []
- for cpv in self._dbapi.cpv_all(use_cache=0):
+ for cpv in self._dbapi.cpv_all():
lines += self._dbapi.aux_get(cpv, ["NEEDED.ELF.2"])[0].split('\n')
# Cache NEEDED.* files avoid doing excessive IO for every rebuild.
self._dbapi.flush_cache()
def checkblockers(self, origdep):
pass
+ def _add(self, pkg_dblink):
+ self._clear_cache(pkg_dblink)
+
+ def _remove(self, pkg_dblink):
+ self._clear_cache(pkg_dblink)
+
+ def _clear_cache(self, pkg_dblink):
+ # Due to 1 second mtime granularity in <python-2.5, mtime checks
+ # are not always sufficient to invalidate vardbapi caches. Therefore,
+ # the caches need to be actively invalidated here.
+ self.mtdircache.pop(pkg_dblink.cat, None)
+ self.matchcache.pop(pkg_dblink.cat, None)
+ self.cpcache.pop(pkg_dblink.mysplit[0], None)
+ from portage import dircache
+ dircache.pop(pkg_dblink.dbcatdir, None)
+
def match(self, origdep, use_cache=1):
"caching match function"
mydep = dep_expand(
"""
if not os.path.exists(self.dbdir):
return
- try:
- for x in os.listdir(self.dbdir):
- os.unlink(self.dbdir+"/"+x)
- os.rmdir(self.dbdir)
- except OSError, e:
- print "!!! Unable to remove db entry for this package."
- print "!!! It is possible that a directory is in this one. Portage will still"
- print "!!! register this package as installed as long as this directory exists."
- print "!!! You may delete this directory with 'rm -Rf "+self.dbdir+"'"
- print "!!! "+str(e)
- print
- sys.exit(1)
-
- # Due to mtime granularity, mtime checks do not always properly
- # invalidate vardbapi caches.
- self.vartree.dbapi.mtdircache.pop(self.cat, None)
- self.vartree.dbapi.matchcache.pop(self.cat, None)
- self.vartree.dbapi.cpcache.pop(self.mysplit[0], None)
+
+ # Check validity of self.dbdir before attempting to remove it.
+ if not self.dbdir.startswith(self.dbroot):
+ writemsg("portage.dblink.delete(): invalid dbdir: %s\n" % \
+ self.dbdir, noiselevel=-1)
+ return
+ import shutil
+ shutil.rmtree(self.dbdir)
+ self.vartree.dbapi._remove(self)
def clearcontents(self):
"""
f.write(line)
f.close()
- # Due to mtime granularity, mtime checks do not always properly
- # invalidate vardbapi caches.
- self.vartree.dbapi.mtdircache.pop(self.cat, None)
- self.vartree.dbapi.matchcache.pop(self.cat, None)
- self.vartree.dbapi.cpcache.pop(self.mysplit[0], None)
+ self.vartree.dbapi._add(self)
contents = self.getcontents()
# regenerate reverse NEEDED map
"WARN": printer.ewarn,
"ERROR": printer.eerror,
"LOG": printer.einfo,
- "QA": printer.ewarn}
+ "QA": printer.ewarn,
+ "BLANK": printer.eblank}
if isinstance(msgcontent, basestring):
msgcontent = [msgcontent]
for line in msgcontent:
# Colors from /etc/init.d/functions.sh
codes["NORMAL"] = esc_seq + "0m"
+codes["BLANK"] = codes["lightgray"]
codes["GOOD"] = codes["green"]
codes["WARN"] = codes["yellow"]
codes["BAD"] = codes["red"]
sys.stdout.flush()
self.__last_e_cmd = "ewarn"
+ def eblank(self, msg):
+ """
+ Shows a blank line. Consecutive eblank calls are all collapsed
+ into a single blank line.
+ """
+ if self.__last_e_cmd == "eblank":
+ return
+ if not self.quiet:
+ if self.__last_e_cmd == "ebegin":
+ sys.stdout.write("\n")
+ sys.stdout.write(colorize("BLANK", " * ") + "\n")
+ sys.stdout.flush()
+ self.__last_e_cmd = "eblank"
+
def ewend(self, errno, *msg):
"""
Indicates the completion of a process, optionally displaying a message