summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-12-06 10:22:54 +0000
committerZac Medico <zmedico@gentoo.org>2009-12-06 10:22:54 +0000
commitd0733a19ea2b08984589c5881b0a99c2ca26e4d6 (patch)
treed26846c08c46bc51337182743d2e6c513f3b37d7
parentAdd 'tla' to the lists of live eclasses. (diff)
downloadportage-multirepo-d0733a19ea2b08984589c5881b0a99c2ca26e4d6.tar.gz
portage-multirepo-d0733a19ea2b08984589c5881b0a99c2ca26e4d6.tar.bz2
portage-multirepo-d0733a19ea2b08984589c5881b0a99c2ca26e4d6.zip
Bug #295715 - Implement a register_success_hook function to complement
register_die_hook, and also add code to ensure the die hooks are called even when the failure is on the python side (like for file collisions). svn path=/main/trunk/; revision=14936
-rwxr-xr-xbin/ebuild.sh11
-rwxr-xr-xbin/isolated-functions.sh1
-rwxr-xr-xbin/misc-functions.sh16
-rw-r--r--man/ebuild.511
-rw-r--r--pym/_emerge/EbuildBuild.py28
-rw-r--r--pym/_emerge/EbuildPhase.py33
-rw-r--r--pym/_emerge/Scheduler.py12
-rw-r--r--pym/portage/__init__.py7
-rw-r--r--pym/portage/dbapi/vartree.py12
9 files changed, 108 insertions, 23 deletions
diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index 3a203860..6915296b 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -267,6 +267,14 @@ register_die_hook() {
done
}
+register_success_hook() {
+ local x
+ for x in $* ; do
+ hasq $x $EBUILD_SUCCESS_HOOKS || \
+ export EBUILD_SUCCESS_HOOKS="$EBUILD_SUCCESS_HOOKS $x"
+ done
+}
+
# Ensure that $PWD is sane whenever possible, to protect against
# exploitation of insecure search path for python -c in ebuilds.
# See bug #239560.
@@ -741,7 +749,8 @@ dyn_clean() {
if [[ $EMERGE_FROM = binary ]] || ! hasq keepwork $FEATURES; then
rm -f "$PORTAGE_BUILDDIR"/.{ebuild_changed,exit_status,logid,unpacked,prepared} \
- "$PORTAGE_BUILDDIR"/.{configured,compiled,tested,packaged}
+ "$PORTAGE_BUILDDIR"/.{configured,compiled,tested,packaged} \
+ "$PORTAGE_BUILDDIR"/.die_hooks
rm -rf "${PORTAGE_BUILDDIR}/build-info"
rm -rf "${WORKDIR}"
diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh
index 4d3c6960..9741419b 100755
--- a/bin/isolated-functions.sh
+++ b/bin/isolated-functions.sh
@@ -156,6 +156,7 @@ die() {
for x in $EBUILD_DEATH_HOOKS; do
${x} "$@" >&2 1>&2
done
+ > "$PORTAGE_BUILDDIR/.die_hooks"
fi
[[ -n ${PORTAGE_LOG_FILE} ]] \
diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
index ef8b0a54..87aaeff5 100755
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
@@ -781,6 +781,22 @@ dyn_rpm() {
die "Failed to move rpm"
}
+die_hooks() {
+ [[ -f $PORTAGE_BUILDDIR/.die_hooks ]] && return
+ local x
+ for x in $EBUILD_DEATH_HOOKS ; do
+ $x >&2
+ done
+ > "$PORTAGE_BUILDDIR/.die_hooks"
+}
+
+success_hooks() {
+ local x
+ for x in $EBUILD_SUCCESS_HOOKS ; do
+ $x
+ done
+}
+
if [ -n "${MISC_FUNCTIONS_ARGS}" ]; then
source_all_bashrcs
[ "$PORTAGE_DEBUG" == "1" ] && set -x
diff --git a/man/ebuild.5 b/man/ebuild.5
index 18db8e8a..b9b4ce62 100644
--- a/man/ebuild.5
+++ b/man/ebuild.5
@@ -703,6 +703,17 @@ VERINS="$(best_version net\-ftp/glftpd)"
.br
(VERINS now has the value "net\-ftp/glftpd\-1.27" if glftpd\-1.27 is installed)
.RE
+.SH "HELPER FUNCTIONS: HOOKS"
+.TP
+\fBregister_die_hook\fR \fI[list of function names]\fR
+Register one or more functions to call when the ebuild fails for any reason,
+including file collisions with other packages.
+.TP
+\fBregister_success_hook\fR \fI[list of function names]\fR
+Register one or more functions to call when the ebuild builds and/or installs
+successfully.
+.TP
+.RE
.SH "HELPER FUNCTIONS: OUTPUT"
.TP
\fBeinfo\fR \fI"disposable message"\fR
diff --git a/pym/_emerge/EbuildBuild.py b/pym/_emerge/EbuildBuild.py
index 930b5c6d..543fb1b0 100644
--- a/pym/_emerge/EbuildBuild.py
+++ b/pym/_emerge/EbuildBuild.py
@@ -10,6 +10,7 @@ from _emerge.CompositeTask import CompositeTask
from _emerge.EbuildMerge import EbuildMerge
from _emerge.EbuildFetchonly import EbuildFetchonly
from _emerge.EbuildBuildDir import EbuildBuildDir
+from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
from portage.util import writemsg
import portage
from portage import os
@@ -215,14 +216,13 @@ class EbuildBuild(CompositeTask):
return
if self.opts.buildpkgonly:
- # Need to call "clean" phase for buildpkgonly mode
- portage.elog.elog_process(self.pkg.cpv, self.settings)
- phase = "clean"
- clean_phase = EbuildPhase(background=self.background,
- pkg=self.pkg, phase=phase,
- scheduler=self.scheduler, settings=self.settings,
- tree=self._tree)
- self._start_task(clean_phase, self._clean_exit)
+ phase = 'success_hooks'
+ success_hooks = MiscFunctionsProcess(
+ background=self.background,
+ commands=[phase], phase=phase, pkg=self.pkg,
+ scheduler=self.scheduler, settings=self.settings)
+ self._start_task(success_hooks,
+ self._buildpkgonly_success_hook_exit)
return
# Continue holding the builddir lock until
@@ -231,6 +231,18 @@ class EbuildBuild(CompositeTask):
self.returncode = packager.returncode
self.wait()
+ def _buildpkgonly_success_hook_exit(self, success_hooks):
+ self._default_exit(success_hooks)
+ self.returncode = None
+ # Need to call "clean" phase for buildpkgonly mode
+ portage.elog.elog_process(self.pkg.cpv, self.settings)
+ phase = 'clean'
+ clean_phase = EbuildPhase(background=self.background,
+ pkg=self.pkg, phase=phase,
+ scheduler=self.scheduler, settings=self.settings,
+ tree=self._tree)
+ self._start_task(clean_phase, self._clean_exit)
+
def _clean_exit(self, clean_phase):
if self._final_exit(clean_phase) != os.EX_OK or \
self.opts.buildpkgonly:
diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py
index 01661b2c..89bdb078 100644
--- a/pym/_emerge/EbuildPhase.py
+++ b/pym/_emerge/EbuildPhase.py
@@ -52,12 +52,7 @@ class EbuildPhase(CompositeTask):
log_file.close()
if self._default_exit(ebuild_process) != os.EX_OK:
- if self.phase != 'clean' and \
- 'noclean' not in self.settings.features and \
- 'fail-clean' in self.settings.features:
- self._fail_clean()
- return
- self.wait()
+ self._die_hooks()
return
settings = self.settings
@@ -92,15 +87,31 @@ class EbuildPhase(CompositeTask):
if self._final_exit(post_phase) != os.EX_OK:
writemsg("!!! post %s failed; exiting.\n" % self.phase,
noiselevel=-1)
- if self.phase != 'clean' and \
- 'noclean' not in self.settings.features and \
- 'fail-clean' in self.settings.features:
- self._fail_clean()
- return
+ self._die_hooks()
+ return
self._current_task = None
self.wait()
return
+ def _die_hooks(self):
+ self.returncode = None
+ phase = 'die_hooks'
+ die_hooks = MiscFunctionsProcess(background=self.background,
+ commands=[phase], phase=phase, pkg=self.pkg,
+ scheduler=self.scheduler, settings=self.settings)
+ self._start_task(die_hooks, self._die_hooks_exit)
+
+ def _die_hooks_exit(self, die_hooks):
+ if self.phase != 'clean' and \
+ 'noclean' not in self.settings.features and \
+ 'fail-clean' in self.settings.features:
+ self._default_exit(die_hooks)
+ self._fail_clean()
+ return
+ self._final_exit(die_hooks)
+ self.returncode = 1
+ self.wait()
+
def _fail_clean(self):
self.returncode = None
portage.elog.elog_process(self.pkg.cpv, self.settings)
diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py
index 9a5e931e..c760c395 100644
--- a/pym/_emerge/Scheduler.py
+++ b/pym/_emerge/Scheduler.py
@@ -40,6 +40,7 @@ from _emerge._find_deep_system_runtime_deps import _find_deep_system_runtime_dep
from _emerge._flush_elog_mod_echo import _flush_elog_mod_echo
from _emerge.JobStatusDisplay import JobStatusDisplay
from _emerge.MergeListItem import MergeListItem
+from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
from _emerge.Package import Package
from _emerge.PackageMerge import PackageMerge
from _emerge.PollScheduler import PollScheduler
@@ -543,9 +544,14 @@ class Scheduler(PollScheduler):
background = self._background
log_path = settings.get("PORTAGE_LOG_FILE")
- ebuild_phase = EbuildPhase(background=background,
- pkg=pkg, phase=phase, scheduler=scheduler,
- settings=settings, tree=pkg_dblink.treetype)
+ if phase in ('die_hooks', 'success_hooks'):
+ ebuild_phase = MiscFunctionsProcess(background=background,
+ commands=[phase], phase=phase, pkg=pkg,
+ scheduler=scheduler, settings=settings)
+ else:
+ ebuild_phase = EbuildPhase(background=background,
+ pkg=pkg, phase=phase, scheduler=scheduler,
+ settings=settings, tree=pkg_dblink.treetype)
ebuild_phase.start()
ebuild_phase.wait()
diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py
index 4f32158b..18cb707e 100644
--- a/pym/portage/__init__.py
+++ b/pym/portage/__init__.py
@@ -6351,6 +6351,13 @@ def prepare_build_dirs(myroot, mysettings, cleanup):
writemsg(_("File Not Found: '%s'\n") % str(e), noiselevel=-1)
return 1
+ # Reset state for things like noauto and keepwork in FEATURES.
+ for x in ('.die_hooks',):
+ try:
+ os.unlink(os.path.join(mysettings['PORTAGE_BUILDDIR'], x))
+ except OSError:
+ pass
+
_prepare_workdir(mysettings)
if mysettings.get('EBUILD_PHASE') != 'fetch':
# Avoid spurious permissions adjustments when fetching with
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 27f2241c..3244fa4e 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -4403,6 +4403,18 @@ class dblink(object):
retval = self.treewalk(mergeroot, myroot, inforoot, myebuild,
cleanup=cleanup, mydbapi=mydbapi, prev_mtimes=prev_mtimes)
+ if retval == os.EX_OK:
+ phase = 'success_hooks'
+ else:
+ phase = 'die_hooks'
+
+ if self._scheduler is None:
+ portage._spawn_misc_sh(self.settings, [phase],
+ phase=phase)
+ else:
+ self._scheduler.dblinkEbuildPhase(
+ self, mydbapi, myebuild, phase)
+
# Process ebuild logfiles
elog_process(self.mycpv, self.settings, phasefilter=filter_mergephases)
if 'noclean' not in self.settings.features and \