Merged from trunk -r13063:13091
authorFabian Groffen <grobian@gentoo.org>
Thu, 12 Mar 2009 20:07:48 +0000 (20:07 -0000)
committerFabian Groffen <grobian@gentoo.org>
Thu, 12 Mar 2009 20:07:48 +0000 (20:07 -0000)
   | 13064    | Use ${x##*/} instead of calling basename.                   |
   | zmedico  |                                                             |

   | 13065    | Bug #262096 - Add separate eerror, elog, eqawarn, and ewarn |
   | zmedico  | binaries for use by non-bash programs running inside the    |
   |          | ebuild environment, such as sandbox.                        |

   | 13066    | Also add an einfo binary.                                   |
   | zmedico  |                                                             |

   | 13067    | Use posix compatible find -perm arguments. Thanks to        |
   | zmedico  | Timothy Redaelli <drizzt@g.o> for reporting.                |

   | 13068    | When translating portage uid/gid to root uid/gid after      |
   | zmedico  | src_install on FreeBSD, temporarily remove all file flags   |
   |          | inside $D in order to avoid EPERM errors. Thanks to Timothy |
   |          | Redaelli <drizzt@g.o> for reporting.                        |

   | 13069    | Make dyn_clean ignore FEATURES=keepwork when [[             |
   | zmedico  | $EMERGE_FROM = binary ]] and remove shutil.rmtree() call    |
   |          | from Binpkg._clean_exit() since dyn_clean is guaranteed to  |
   |          | do a full clean now.                                        |

   | 13070    | Bug #261992 - Inside Binpkg._prefetch_exit(), avoid         |
   | zmedico  | potention issues with shutil.rmtree() by just doing a       |
   |          | minimal cleanup.                                            |

   | 13071    | Bug #261992 - Replace the EbuildBuildDir.clean() method     |
   | zmedico  | with a clean_log() method since log cleanup is all that's   |
   |          | currently needed and shutil.rmtree() can fail with          |
   |          | "OSError: [Errno 36] File name too long" due to strange     |
   |          | file names, or on FreeBSD it can fail with EPERM due to     |
   |          | file flags in $D.                                           |

   | 13072    | Update docstring for EbuildBuildDir.clean_log().            |
   | zmedico  |                                                             |

   | 13088    | Bug #261670 - Automatically revert the CHOST metadata to    |
   | zmedico  | the initial value after src_install, in case the ebuild has |
   |          | changed it.                                                 |

   | 13090    | cleanup sandbox env var handling -- make sure we dont       |
   | SpankMan | insert empty : sections and avoid unnecessary eval usage    |

   | 13091    | Filter _sb_append_var in save_ebuild_env().                 |
   | zmedico  |                                                             |

svn path=/main/branches/prefix/; revision=13099

bin/ebuild-helpers/doexe
bin/ebuild-helpers/eerror [new symlink]
bin/ebuild-helpers/einfo [new symlink]
bin/ebuild-helpers/elog [new file with mode: 0755]
bin/ebuild-helpers/eqawarn [new symlink]
bin/ebuild-helpers/ewarn [new symlink]
bin/ebuild.sh
bin/isolated-functions.sh
bin/misc-functions.sh
pym/_emerge/__init__.py
pym/portage/__init__.py

index bd278e52e9ee32a7304b73034969d3a33f2ed938..34818ccb11b015f54da527acd77713053963527a 100755 (executable)
@@ -17,7 +17,7 @@ fi
 for x in "$@" ; do
        if [ -L "${x}" ] ; then
                cp "${x}" "${T}"
-               mysrc="${T}"/$(basename "${x}")
+               mysrc="$T/${x##*/}"
        elif [ -d "${x}" ] ; then
                vecho "doexe: warning, skipping directory ${x}"
                continue
diff --git a/bin/ebuild-helpers/eerror b/bin/ebuild-helpers/eerror
new file mode 120000 (symlink)
index 0000000..a403c75
--- /dev/null
@@ -0,0 +1 @@
+elog
\ No newline at end of file
diff --git a/bin/ebuild-helpers/einfo b/bin/ebuild-helpers/einfo
new file mode 120000 (symlink)
index 0000000..a403c75
--- /dev/null
@@ -0,0 +1 @@
+elog
\ No newline at end of file
diff --git a/bin/ebuild-helpers/elog b/bin/ebuild-helpers/elog
new file mode 100755 (executable)
index 0000000..2e2674b
--- /dev/null
@@ -0,0 +1,8 @@
+#!@PORTAGE_BASH@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+source "${PORTAGE_BIN_PATH:-${EPREFIX}/usr/lib/portage/bin}"/isolated-functions.sh
+
+${0##*/} "$@"
diff --git a/bin/ebuild-helpers/eqawarn b/bin/ebuild-helpers/eqawarn
new file mode 120000 (symlink)
index 0000000..a403c75
--- /dev/null
@@ -0,0 +1 @@
+elog
\ No newline at end of file
diff --git a/bin/ebuild-helpers/ewarn b/bin/ebuild-helpers/ewarn
new file mode 120000 (symlink)
index 0000000..a403c75
--- /dev/null
@@ -0,0 +1 @@
+elog
\ No newline at end of file
index e2935d52a27a96c5c3de7f510b286d745706b229..790b24571af07515e5cbdd14a94db5a1e27701b9 100755 (executable)
@@ -6,10 +6,9 @@
 PORTAGE_BIN_PATH="${PORTAGE_BIN_PATH:-@PORTAGE_BASE@/bin}"
 PORTAGE_PYM_PATH="${PORTAGE_PYM_PATH:-@PORTAGE_BASE@/pym}"
 
-SANDBOX_PREDICT="${SANDBOX_PREDICT}:/proc/self/maps:/dev/console:/dev/random"
-export SANDBOX_PREDICT
-export SANDBOX_WRITE="${SANDBOX_WRITE}:/dev/shm:/dev/stdout:/dev/stderr:${PORTAGE_TMPDIR}"
-export SANDBOX_READ="${SANDBOX_READ}:/:/dev/shm:/dev/stdin:${PORTAGE_TMPDIR}"
+export SANDBOX_PREDICT="${SANDBOX_PREDICT:+${SANDBOX_PREDICT}:}/proc/self/maps:/dev/console:/dev/random"
+export SANDBOX_WRITE="${SANDBOX_WRITE:+${SANDBOX_WRITE}:}/dev/shm:/dev/stdout:/dev/stderr:${PORTAGE_TMPDIR}"
+export SANDBOX_READ="${SANDBOX_READ:+${SANDBOX_READ}:}/:/dev/shm:/dev/stdin:${PORTAGE_TMPDIR}"
 # Don't use sandbox's BASH_ENV for new shells because it does
 # 'source /etc/profile' which can interfere with the build
 # environment by modifying our PATH.
@@ -85,25 +84,19 @@ source "${PORTAGE_BIN_PATH}/isolated-functions.sh"  &>/dev/null
 export SANDBOX_ON="0"
 
 # sandbox support functions; defined prior to profile.bashrc srcing, since the profile might need to add a default exception (/usr/lib64/conftest fex)
-addread() {
-       [[ -z $1 || -n $2 ]] && die "Usage: addread <colon-delimited list of paths>"
-       export SANDBOX_READ="$SANDBOX_READ:$1"
-}
-
-addwrite() {
-       [[ -z $1 || -n $2 ]] && die "Usage: addwrite <colon-delimited list of paths>"
-       export SANDBOX_WRITE="$SANDBOX_WRITE:$1"
-}
-
-adddeny() {
-       [[ -z $1 || -n $2 ]] && die "Usage: adddeny <colon-delimited list of paths>"
-       export SANDBOX_DENY="$SANDBOX_DENY:$1"
-}
-
-addpredict() {
-       [[ -z $1 || -n $2 ]] && die "Usage: addpredict <colon-delimited list of paths>"
-       export SANDBOX_PREDICT="$SANDBOX_PREDICT:$1"
-}
+_sb_append_var() {
+       local _v=$1 ; shift
+       local var="SANDBOX_${_v}"
+       [[ -z $1 || -n $2 ]] && die "Usage: add$(echo ${_v} | LC_ALL=C tr :upper: :lower:) <colon-delimited list of paths>"
+       export ${var}="${!var:+${!var}:}$1"
+}
+# bash-4 version:
+# local var="SANDBOX_${1^^}"
+# addread() { _sb_append_var ${0#add} "$@" ; }
+addread()    { _sb_append_var READ    "$@" ; }
+addwrite()   { _sb_append_var WRITE   "$@" ; }
+adddeny()    { _sb_append_var DENY    "$@" ; }
+addpredict() { _sb_append_var PREDICT "$@" ; }
 
 lchown() {
        chown -h "$@"
@@ -721,11 +714,12 @@ dyn_clean() {
        rm -rf "${PORTAGE_BUILDDIR}/image" "${PORTAGE_BUILDDIR}/homedir"
        rm -f "${PORTAGE_BUILDDIR}/.installed"
 
-       if ! hasq keeptemp $FEATURES && ! hasq keepwork $FEATURES ; then
+       if [[ $EMERGE_FROM = binary ]] || \
+               ! hasq keeptemp $FEATURES && ! hasq keepwork $FEATURES ; then
                rm -rf "${T}"
        fi
 
-       if ! hasq keepwork $FEATURES; then
+       if [[ $EMERGE_FROM = binary ]] || ! hasq keepwork $FEATURES; then
                rm -f "$PORTAGE_BUILDDIR"/.{exit_status,logid,unpacked,prepared} \
                        "$PORTAGE_BUILDDIR"/.{configured,compiled,tested,packaged}
 
@@ -958,13 +952,14 @@ dyn_test() {
                ewarn "Skipping make test/check due to ebuild restriction."
                vecho ">>> Test phase [explicitly disabled]: ${CATEGORY}/${PF}"
        else
+               local save_sp=${SANDBOX_PREDICT}
                addpredict /
                ebuild_phase pre_src_test
                ebuild_phase src_test
                touch "$PORTAGE_BUILDDIR/.tested" || \
                        die "Failed to 'touch .tested' in $PORTAGE_BUILDDIR"
                ebuild_phase post_src_test
-               SANDBOX_PREDICT="${SANDBOX_PREDICT%:/}"
+               SANDBOX_PREDICT=${save_sp}
        fi
 
        trap - SIGINT SIGQUIT
@@ -1844,7 +1839,7 @@ if ! hasq "$EBUILD_PHASE" clean cleanrm depend && \
                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}
+               export PORTAGE_${x}=${!x}
        done
        PORTAGE_SANDBOX_ON=${SANDBOX_ON}
        export SANDBOX_ON=1
@@ -1856,11 +1851,15 @@ if ! hasq "$EBUILD_PHASE" clean cleanrm depend && \
        # until we've merged them with our current values.
        export SANDBOX_ON=0
        for x in SANDBOX_DENY SANDBOX_PREDICT SANDBOX_READ SANDBOX_WRITE ; do
-               eval y=\${PORTAGE_${x}}
-               if [ "${y}" != "${!x}" ] ; then
-                       eval export ${x}=\"$(echo -n "${y}:${!x}" | tr ":" "\0" | \
-                               sort -z -u | tr "\0" ":")\"
+               y="PORTAGE_${x}"
+               if [ -z "${!x}" ] ; then
+                       export ${x}=${!y}
+               elif [ -n "${!y}" ] && [ "${!y}" != "${!x}" ] ; then
+                       # filter out dupes
+                       export ${x}=$(printf "${!y}:${!x}" | tr ":" "\0" | \
+                               sort -z -u | tr "\0" ":")
                fi
+               export ${x}=${!x%:}
                unset PORTAGE_${x}
        done
        unset x y
index b3256452cea5e453ced499adfa9d6006d30d9f31..839b8da28fe830624cab44eeaa1d27152a88d55d 100755 (executable)
@@ -503,7 +503,7 @@ save_ebuild_env() {
                        esyslog einfo einfon ewarn eerror ebegin _eend eend KV_major \
                        KV_minor KV_micro KV_to_int get_KV unset_colors set_colors has \
                        hasg hasgq hasv hasq qa_source qa_call \
-                       addread addwrite adddeny addpredict \
+                       addread addwrite adddeny addpredict _sb_append_var \
                        lchown lchgrp esyslog use usev useq has_version portageq \
                        best_version use_with use_enable register_die_hook check_KV \
                        keepdir unpack strip_duplicate_slashes econf einstall \
index fa4b77b1e879b304405f4fd0d853a457bba973fe..5ef5f53b478353b08806f8ed9956034e5de9dda1 100644 (file)
@@ -75,8 +75,8 @@ install_qa_check() {
                f=$(scanelf -qyRF '%r %p' "${ED}" | grep -E "(${PORTAGE_BUILDDIR}|: |::|^:|^ )")
                # Reject set*id binaries with $ORIGIN in RPATH #260331
                x=$(
-                       find "${D}" -type f -perm /6000 -print0 | xargs -0 \
-                       scanelf -qyRF '%r %p' | grep '$ORIGIN'
+                       find "${D}" -type f \( -perm -u+s -o -perm -g+s \) -print0 | \
+                       xargs -0 scanelf -qyRF '%r %p' | grep '$ORIGIN'
                )
                if [[ -n ${f}${x} ]] ; then
                        vecho -ne '\a\n'
index eda2ca394aa83f862b0147d6b27a95f05055f4aa..54ea57340e8a9ac6fa3c7f5874e6819201210df8 100644 (file)
@@ -2534,7 +2534,7 @@ class EbuildFetcher(SpawnProcess):
                if not self.prefetch:
                        self._build_dir = EbuildBuildDir(pkg=self.pkg, settings=settings)
                        self._build_dir.lock()
-                       self._build_dir.clean()
+                       self._build_dir.clean_log()
                        portage.prepare_build_dirs(self.pkg.root, self._build_dir.settings, 0)
                        if self.logfile is None:
                                self.logfile = settings.get("PORTAGE_LOG_FILE")
@@ -2605,7 +2605,7 @@ class EbuildFetcher(SpawnProcess):
                                portage.elog.elog_process(self.pkg.cpv, self._build_dir.settings)
                        features = self._build_dir.settings.features
                        if self.returncode == os.EX_OK:
-                               self._build_dir.clean()
+                               self._build_dir.clean_log()
                        self._build_dir.unlock()
                        self.config_pool.deallocate(self._build_dir.settings)
                        self._build_dir = None
@@ -2660,18 +2660,15 @@ class EbuildBuildDir(SlotObject):
                        if catdir_lock is not None:
                                portage.locks.unlockdir(catdir_lock)
 
-       def clean(self):
-               """Uses shutil.rmtree() rather than spawning a 'clean' phase. Disabled
-               by keepwork or keeptemp in FEATURES."""
+       def clean_log(self):
+               """Discard existing log."""
                settings = self.settings
-               features = settings.features
-               if not ("keepwork" in features or "keeptemp" in features):
+
+               for x in ('.logid', 'temp/build.log'):
                        try:
-                               shutil.rmtree(settings["PORTAGE_BUILDDIR"])
-                       except EnvironmentError, e:
-                               if e.errno != errno.ENOENT:
-                                       raise
-                               del e
+                               os.unlink(os.path.join(settings["PORTAGE_BUILDDIR"], x))
+                       except OSError:
+                               pass
 
        def unlock(self):
                if self._lock_obj is None:
@@ -3219,6 +3216,7 @@ class EbuildPhase(CompositeTask):
                settings = self.settings
 
                if self.phase == "install":
+                       portage._post_src_install_chost_fix(settings)
                        portage._post_src_install_uid_fix(settings)
 
                post_phase_cmds = self._post_phase_cmds.get(self.phase)
@@ -3440,12 +3438,10 @@ class Binpkg(CompositeTask):
                pkg_count = self.pkg_count
                if not (self.opts.pretend or self.opts.fetchonly):
                        self._build_dir.lock()
-                       try:
-                               shutil.rmtree(self._build_dir.dir_path)
-                       except EnvironmentError, e:
-                               if e.errno != errno.ENOENT:
-                                       raise
-                               del e
+                       # If necessary, discard old log so that we don't
+                       # append to it.
+                       self._build_dir.clean_log()
+                       # Initialze PORTAGE_LOG_FILE.
                        portage.prepare_build_dirs(self.settings["ROOT"], self.settings, 1)
                fetcher = BinpkgFetcher(background=self.background,
                        logfile=self.settings.get("PORTAGE_LOG_FILE"), pkg=self.pkg,
@@ -3537,13 +3533,6 @@ class Binpkg(CompositeTask):
 
                dir_path = self._build_dir.dir_path
 
-               try:
-                       shutil.rmtree(dir_path)
-               except (IOError, OSError), e:
-                       if e.errno != errno.ENOENT:
-                               raise
-                       del e
-
                infloc = self._infloc
                pkg = self.pkg
                pkg_path = self._pkg_path
index 3527fa7deba252c6637faf1c302ad0a3748f29ff..2a5248ff8f084eee0e648e5464806c2b5e2b4581 100644 (file)
@@ -4743,6 +4743,7 @@ def spawnebuild(mydo, actionmap, mysettings, debug, alwaysdep=0,
        if mydo == "install":
                _check_build_log(mysettings)
                if phase_retval == os.EX_OK:
+                       _post_src_install_chost_fix(mysettings)
                        phase_retval = _post_src_install_checks(mysettings)
 
        if mydo == "test" and phase_retval != os.EX_OK and \
@@ -4893,6 +4894,17 @@ def _check_build_log(mysettings, out=None):
                msg.extend("\t" + line for line in make_jobserver)
                _eqawarn(msg)
 
+def _post_src_install_chost_fix(settings):
+       """
+       It's possible that the ebuild has changed the
+       CHOST variable, so revert it to the initial
+       setting.
+       """
+       chost = settings.get('CHOST')
+       if chost:
+               write_atomic(os.path.join(settings['PORTAGE_BUILDDIR'],
+                       'build-info', 'CHOST'), chost + '\n')
+
 def _post_src_install_uid_fix(mysettings):
        """
        Files in $D with user and group bits that match the "portage"
@@ -4903,6 +4915,17 @@ def _post_src_install_uid_fix(mysettings):
        """
        inst_uid = int(mysettings["PORTAGE_INST_UID"])
        inst_gid = int(mysettings["PORTAGE_INST_GID"])
+
+       if bsd_chflags:
+               # Temporarily remove all of the flags in order to avoid EPERM errors.
+               os.system("mtree -c -p %s -k flags > %s" % \
+                       (_shell_quote(mysettings["D"]),
+                       _shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree"))))
+               os.system("chflags -R noschg,nouchg,nosappnd,nouappnd %s" % \
+                       (_shell_quote(mysettings["D"]),))
+               os.system("chflags -R nosunlnk,nouunlnk %s 2>/dev/null" % \
+                       (_shell_quote(mysettings["D"]),))
+
        for parent, dirs, files in os.walk(mysettings["D"]):
                for fname in chain(dirs, files):
                        fpath = os.path.join(parent, fname)
@@ -4920,6 +4943,12 @@ def _post_src_install_uid_fix(mysettings):
                                mode=mystat.st_mode, stat_cached=mystat,
                                follow_links=False)
 
+       if bsd_chflags:
+               # Restore all of the flags saved above.
+               os.system("mtree -e -p %s -U -k flags < %s > /dev/null" % \
+                       (_shell_quote(mysettings["D"]),
+                       _shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree"))))
+
 def _post_pkg_preinst_cmd(mysettings):
        """
        Post phase logic and tasks that have been factored out of