From: Fabian Groffen Date: Fri, 31 Jul 2009 07:41:14 +0000 (-0000) Subject: Merged from trunk -r13857:13865 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=2f00fb41e72f947453e90044158276bd43fa3508;p=portage.git Merged from trunk -r13857:13865 | 13858 | Add get_updated_config_files in portage API | | volkmar | chk_updated_cfg_files in _emerge API is now using | | | get_updated_config_files It lets other app to get updated | | | config files without ouputs | | 13859 | Rename get_updated_config_files() to | | zmedico | find_updated_config_files() and make it an iterator of | | | tuples. | | 13860 | Updating find_updated_config_files function description | | volkmar | | | 13861 | Move the setsid code (from bug #278895) as early as | | zmedico | possible. | | 13862 | Fix breakage in owners() handling of abs paths. | | zmedico | | | 13863 | Add a python-based setsid script for use with USERLAND=BSD. | | zmedico | | | 13864 | Bug #276264 - Advise manual removal of the metadata/cache/ | | zmedico | direcory when using eclass-overrides. | | 13865 | In depgraph._show_slot_collision_notice(), display $ROOT (if | | zmedico | not /) with each slot atom. | svn path=/main/branches/prefix/; revision=13869 --- diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 6ee314564..150d98149 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -18,6 +18,28 @@ if [ -n "${PORTAGE_ROOTPATH}" ] ; then unset PORTAGE_ROOTPATH fi +ROOTPATH=${ROOTPATH##:} +ROOTPATH=${ROOTPATH%%:} +PREROOTPATH=${PREROOTPATH##:} +PREROOTPATH=${PREROOTPATH%%:} +#PATH=$PORTAGE_BIN_PATH/ebuild-helpers:$PREROOTPATH${PREROOTPATH:+:}/usr/local/sbin:/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin${ROOTPATH:+:}$ROOTPATH +# PREFIX: we deviate in path order, should we split up DEFAULT_PATH? +PATH="$PORTAGE_BIN_PATH/ebuild-helpers:$PREROOTPATH${PREROOTPATH:+:}${DEFAULT_PATH}:${ROOTPATH:+:}$ROOTPATH" +export PATH + +if [[ -z $PORTAGE_SETSID && -n $1 && $1 != depend ]] ; then + # If available, use setsid to create a new login session so that we can use + # SIGHUP to ensure that no orphaned subprocesses are left running. + if type -P setsid >/dev/null ; then + export PORTAGE_SETSID=1 + exec setsid "$PORTAGE_BIN_PATH/ebuild.sh" "$@" + elif [[ -x $PORTAGE_BIN_PATH/setsid ]] ; then + export PORTAGE_SETSID=1 + exec "$PORTAGE_BIN_PATH/setsid" "$PORTAGE_BIN_PATH/ebuild.sh" "$@" + fi +fi +[[ $PORTAGE_SETSID = 1 ]] && trap 'trap : SIGHUP ; kill -s SIGHUP 0 ;' EXIT + # These two functions wrap sourcing and calling respectively. At present they # perform a qa check to make sure eclasses and ebuilds and profiles don't mess # with shell opts (shopts). Ebuilds/eclasses changing shopts should reset them @@ -64,26 +86,6 @@ unalias -a # Unset some variables that break things. unset GZIP BZIP BZIP2 CDPATH GREP_OPTIONS GREP_COLOR GLOBIGNORE -ROOTPATH=${ROOTPATH##:} -ROOTPATH=${ROOTPATH%%:} -PREROOTPATH=${PREROOTPATH##:} -PREROOTPATH=${PREROOTPATH%%:} -#PATH=$PORTAGE_BIN_PATH/ebuild-helpers:$PREROOTPATH${PREROOTPATH:+:}/usr/local/sbin:/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin${ROOTPATH:+:}$ROOTPATH -# PREFIX: we deviate in path order, should we split up DEFAULT_PATH? -PATH="$PORTAGE_BIN_PATH/ebuild-helpers:$PREROOTPATH${PREROOTPATH:+:}${DEFAULT_PATH}:${ROOTPATH:+:}$ROOTPATH" -export PATH - -if [[ -z $PORTAGE_SETSID && \ - -n $EBUILD_SH_ARGS && $EBUILD_SH_ARGS != depend ]] ; then - if type -P setsid >/dev/null ; then - # Use setsid to create a new login session so that we can use SIGHUP - # to ensure that no orphaned subprocesses are left running. - export PORTAGE_SETSID=1 - exec setsid "$PORTAGE_BIN_PATH/ebuild.sh" $EBUILD_SH_ARGS - fi -fi -trap '[[ $PORTAGE_SETSID = 1 ]] && { trap : SIGHUP ; kill -s SIGHUP 0 ; }' EXIT - source "${PORTAGE_BIN_PATH}/isolated-functions.sh" &>/dev/null # Set IMAGE for minimal backward compatibility with diff --git a/bin/portageq b/bin/portageq index 38d797639..d154ce609 100755 --- a/bin/portageq +++ b/bin/portageq @@ -198,7 +198,7 @@ def owners(argv): if is_basename: files.append(f) else: - files.append(f[len(root):]) + files.append(f[len(root)-1:]) owners = vardb._owners.get_owners(files) diff --git a/bin/setsid b/bin/setsid new file mode 100755 index 000000000..1be1e55c2 --- /dev/null +++ b/bin/setsid @@ -0,0 +1,10 @@ +#!/usr/bin/python -O +# Copyright 2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +import os +import sys + +os.setsid() +os.execl(sys.argv[1], *sys.argv[1:]) diff --git a/man/portage.5 b/man/portage.5 index 3a7043995..a5c438612 100644 --- a/man/portage.5 +++ b/man/portage.5 @@ -558,8 +558,9 @@ are inherently \fBnot\fR \fIsite\-specific\fR. \fBWARNING:\fR Use of eclass inheritance (especially due to \fBeclass\-overrides\fR) may trigger performance issues under some circumstances (see \fBbug #124041\fR). When using \fBeclass\-overrides\fR, due to bug #276264, you must ensure that -your portage tree does not contain a metadata/cache/. For example, you -should set PORTAGE_RSYNC_EXTRA_OPTS="\-\-exclude=/metadata/cache" in +your portage tree does not contain a metadata/cache/ directory. If that +directory exists then you should remove it entirely, and set +PORTAGE_RSYNC_EXTRA_OPTS="\-\-exclude=/metadata/cache" in make.conf in order to exclude the metadata/cache/ directory during \fBemerge\fR(1) \-\-sync operations. diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 758f05493..4fed7955b 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -2660,58 +2660,20 @@ def load_emerge_config(trees=None): return settings, trees, mtimedb def chk_updated_cfg_files(target_root, config_protect): - if config_protect: - #number of directories with some protect files in them - procount=0 - for x in config_protect: - x = os.path.join(target_root, x.lstrip(os.path.sep)) - if not os.access(x, os.W_OK): - # Avoid Permission denied errors generated - # later by `find`. - continue - try: - mymode = os.lstat(x).st_mode - except OSError: - continue - if stat.S_ISLNK(mymode): - # We want to treat it like a directory if it - # is a symlink to an existing directory. - try: - real_mode = os.stat(x).st_mode - if stat.S_ISDIR(real_mode): - mymode = real_mode - except OSError: - pass - if stat.S_ISDIR(mymode): - mycommand = "find '%s' -name '.*' -type d -prune -o -name '._cfg????_*'" % x - else: - mycommand = "find '%s' -maxdepth 1 -name '._cfg????_%s'" % \ - os.path.split(x.rstrip(os.path.sep)) - mycommand += " ! -name '.*~' ! -iname '.*.bak' -print0" - a = commands.getstatusoutput(mycommand) - if a[0] != 0: - sys.stderr.write(" %s error scanning '%s': " % (bad("*"), x)) - sys.stderr.flush() - # Show the error message alone, sending stdout to /dev/null. - os.system(mycommand + " 1>/dev/null") - else: - files = a[1].split('\0') - # split always produces an empty string as the last element - if files and not files[-1]: - del files[-1] - if files: - procount += 1 - print "\n"+colorize("WARN", " * IMPORTANT:"), - if stat.S_ISDIR(mymode): - print "%d config files in '%s' need updating." % \ - (len(files), x) - else: - print "config file '%s' needs updating." % x - - if procount: - print " "+yellow("*")+" See the "+colorize("INFORM","CONFIGURATION FILES")+ \ - " section of the " + bold("emerge") - print " "+yellow("*")+" man page to learn how to update config files." + result = list( + portage.util.find_updated_config_files(target_root, config_protect)) + + for x in result: + print "\n"+colorize("WARN", " * IMPORTANT:"), + if not x[1]: # it's a protected file + print "config file '%s' needs updating." % x[0] + else: # it's a protected dir + print "%d config files in '%s' need updating." % (len(x[1]), x[0]) + + if result: + print " "+yellow("*")+" See the "+colorize("INFORM","CONFIGURATION FILES")\ + + " section of the " + bold("emerge") + print " "+yellow("*")+" man page to learn how to update config files." def display_news_notification(root_config, myopts): target_root = root_config.root diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 8feef733a..1cfd0d693 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -398,6 +398,8 @@ class depgraph(object): for (slot_atom, root), slot_nodes \ in self._dynamic_config._slot_collision_info.iteritems(): msg.append(str(slot_atom)) + if root != '/': + msg.append(" for %s" % (root,)) msg.append("\n\n") for node in slot_nodes: diff --git a/pym/portage/util.py b/pym/portage/util.py index 91f831bab..376b6bac8 100644 --- a/pym/portage/util.py +++ b/pym/portage/util.py @@ -5,13 +5,14 @@ __all__ = ['apply_permissions', 'apply_recursive_permissions', 'apply_secpass_permissions', 'apply_stat_permissions', 'atomic_ofstream', 'cmp_sort_key', 'ConfigProtect', 'dump_traceback', 'ensure_dirs', - 'getconfig', 'getlibpaths', 'grabdict', 'grabdict_package', 'grabfile', - 'grabfile_package', 'grablines', 'initialize_logger', 'LazyItemsDict', - 'map_dictlist_vals', 'new_protect_filename', 'normalize_path', - 'pickle_read', 'stack_dictlist', 'stack_dicts', 'stack_lists', - 'unique_array', 'varexpand', 'write_atomic', 'writedict', 'writemsg', - 'writemsg_level', 'writemsg_stdout'] - + 'find_updated_config_files', 'getconfig', 'getlibpaths', 'grabdict', + 'grabdict_package', 'grabfile', 'grabfile_package', 'grablines', + 'initialize_logger', 'LazyItemsDict', 'map_dictlist_vals', + 'new_protect_filename', 'normalize_path', 'pickle_read', 'stack_dictlist', + 'stack_dicts', 'stack_lists', 'unique_array', 'varexpand', 'write_atomic', + 'writedict', 'writemsg', 'writemsg_level', 'writemsg_stdout'] + +import commands import codecs import os import errno @@ -1291,6 +1292,59 @@ def new_protect_filename(mydest, newmd5=None): return old_pfile return new_pfile +def find_updated_config_files(target_root, config_protect): + """ + Return a tuple of configuration files that needs to be updated. + The tuple contains lists organized like this: + [ protected_dir, file_list ] + If the protected config isn't a protected_dir but a procted_file, list is: + [ protected_file, None ] + If no configuration files needs to be updated, None is returned + """ + + if config_protect: + # directories with some protect files in them + for x in config_protect: + files = [] + + x = os.path.join(target_root, x.lstrip(os.path.sep)) + if not os.access(x, os.W_OK): + continue + try: + mymode = os.lstat(x).st_mode + except OSError: + continue + + if stat.S_ISLNK(mymode): + # We want to treat it like a directory if it + # is a symlink to an existing directory. + try: + real_mode = os.stat(x).st_mode + if stat.S_ISDIR(real_mode): + mymode = real_mode + except OSError: + pass + + if stat.S_ISDIR(mymode): + mycommand = \ + "find '%s' -name '.*' -type d -prune -o -name '._cfg????_*'" % x + else: + mycommand = "find '%s' -maxdepth 1 -name '._cfg????_%s'" % \ + os.path.split(x.rstrip(os.path.sep)) + mycommand += " ! -name '.*~' ! -iname '.*.bak' -print0" + a = commands.getstatusoutput(mycommand) + + if a[0] == 0: + files = a[1].split('\0') + # split always produces an empty string as the last element + if files and not files[-1]: + del files[-1] + if files: + if stat.S_ISDIR(mymode): + yield (x, files) + else: + yield (x, None) + def getlibpaths(root): """ Return a list of paths that are used for library lookups """