From e3b988902eb2796f6cafe1c2d671180edd116620 Mon Sep 17 00:00:00 2001 From: Kito Date: Sat, 18 Mar 2006 17:17:05 +0000 Subject: [PATCH] merge with trunk rev 2921:2936 svn path=/main/branches/prefix/; revision=2937 --- bin/ebuild.sh | 4 +- bin/emerge-webrsync | 4 +- pym/portage.py | 244 +++++++++++++++++--------------------------- pym/portage_util.py | 43 +++++++- 4 files changed, 142 insertions(+), 153 deletions(-) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index d0a6f75b4..10479ded8 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -823,7 +823,7 @@ dyn_unpack() { fi if [ ! -d "${WORKDIR}" ]; then - install -m ${PORTAGE_WORKDIR_MODE-0700} -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'" + install -m ${PORTAGE_WORKDIR_MODE:-0700} -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'" fi cd "${WORKDIR}" || die "Directory change failed: \`cd '${WORKDIR}'\`" echo ">>> Unpacking source..." @@ -1226,7 +1226,7 @@ dyn_help() { debug-print() { # if $T isn't defined, we're in dep calculation mode and # shouldn't do anything - [ -z "$T" ] && return 0 + [ ! -d "$T" ] && return 0 while [ "$1" ]; do diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync index 4d5849f06..3c1f1d50b 100755 --- a/bin/emerge-webrsync +++ b/bin/emerge-webrsync @@ -11,6 +11,7 @@ PORTAGE_NICENESS="$(@PORTAGE_BASE@/bin/portageq envvar PORTAGE_NICENESS)" if [ -n "${PORTAGE_NICENESS}" ]; then renice $PORTAGE_NICENESS $$ > /dev/null fi + GENTOO_MIRRORS="${GENTOO_MIRRORS} $(@PORTAGE_BASE@/bin/portageq gentoo_mirrors)" PORTDIR="$(@PORTAGE_BASE@/bin/portageq portdir)" FETCHCOMMAND="$(@PORTAGE_BASE@/bin/portageq envvar FETCHCOMMAND)" @@ -18,6 +19,7 @@ USERLAND="$(@PORTAGE_BASE@/bin/portageq envvar USERLAND)" DISTDIR="$(@PORTAGE_BASE@/bin/portageq envvar PORTAGE_TMPDIR)/emerge-webrsync" PORTAGE_INST_UID="$(@PORTAGE_BASE@/bin/portageq envvar PORTAGE_INST_UID)" PORTAGE_INST_GID="$(@PORTAGE_BASE@/bin/portageq envvar PORTAGE_INST_GID)" + if [ ! -d $DISTDIR ] ; then mkdir -p $DISTDIR fi @@ -73,7 +75,7 @@ sync_local() { rm -rf portage fi echo "transferring metadata/cache" - emerge metadata + emerge --metadata } echo "Fetching most recent snapshot" diff --git a/pym/portage.py b/pym/portage.py index 968b42ba7..d931e967d 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -75,7 +75,7 @@ try: portage_uid, portage_gid import portage_util - from portage_util import atomic_ofstream, apply_secpass_permissions, \ + from portage_util import atomic_ofstream, apply_secpass_permissions, apply_recursive_permissions, \ dump_traceback, getconfig, grabdict, grabdict_package, grabfile, grabfile_package, \ map_dictlist_vals, pickle_read, pickle_write, stack_dictlist, stack_dicts, stack_lists, \ unique_array, varexpand, writedict, writemsg, writemsg_stdout, write_atomic @@ -2488,139 +2488,103 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, t def prepare_build_dirs(myroot, mysettings, cleanup): - if not os.path.exists(mysettings["BUILD_PREFIX"]): - os.makedirs(mysettings["BUILD_PREFIX"]) - apply_secpass_permissions(mysettings["BUILD_PREFIX"], - uid=portage_uid, gid=portage_gid, mode=00775) + clean_dirs = [mysettings["HOME"]] # We enable cleanup when we want to make sure old cruft (such as the old # environment) doesn't interfere with the current phase. if cleanup: - if os.path.exists(mysettings["T"]): - shutil.rmtree(mysettings["T"]) - if not os.path.exists(mysettings["T"]): - os.makedirs(mysettings["T"]) - apply_secpass_permissions(mysettings["T"], - uid=portage_uid, gid=portage_gid, mode=02770) - - logdir = mysettings["T"]+"/logging" - if not os.path.exists(logdir): - os.makedirs(logdir) - apply_secpass_permissions(logdir, - uid=portage_uid, gid=portage_gid, mode=0770) - - try: # XXX: negative RESTRICT - if not (("nouserpriv" in string.split(mysettings["PORTAGE_RESTRICT"])) or \ - ("userpriv" in string.split(mysettings["PORTAGE_RESTRICT"]))): - if ("userpriv" in features) and (portage_uid and portage_gid): - if (secpass==2): - if os.path.exists(mysettings["HOME"]): - # XXX: Potentially bad, but held down by HOME replacement above. - spawn("rm -Rf "+mysettings["HOME"],mysettings, free=1) - if not os.path.exists(mysettings["HOME"]): - os.makedirs(mysettings["HOME"]) - elif ("userpriv" in features): - print "!!! Disabling userpriv from features... Portage UID/GID not valid." - del features[features.index("userpriv")] - except SystemExit, e: - raise - except Exception, e: - print "!!! Couldn't empty HOME:",mysettings["HOME"] - print "!!!",e - - try: - # no reason to check for depend since depend returns above. - for myvar in ("BUILD_PREFIX", "PORTAGE_BUILDDIR"): - if not os.path.exists(mysettings[myvar]): - os.makedirs(mysettings[myvar]) - apply_secpass_permissions(mysettings[myvar], - uid=portage_uid, gid=portage_gid) - except OSError, e: - print "!!! File system problem. (ReadOnly? Out of space?)" - print "!!! Perhaps: rm -Rf",mysettings["BUILD_PREFIX"] - print "!!!",str(e) - return 1 + clean_dirs.append(mysettings["T"]) - try: - if not os.path.exists(mysettings["HOME"]): - os.makedirs(mysettings["HOME"]) - apply_secpass_permissions(mysettings["HOME"], - uid=portage_uid, gid=portage_gid, mode=02770) - except OSError, e: - print "!!! File system problem. (ReadOnly? Out of space?)" - print "!!! Failed to create fake home directory in PORTAGE_BUILDDIR" - print "!!!",str(e) - return 1 + for clean_dir in clean_dirs: + try: + shutil.rmtree(clean_dir) + except OSError, oe: + if errno.ENOENT == oe.errno: + pass + elif errno.EPERM == oe.errno: + writemsg("%s\n" % oe) + writemsg("Operation Not Permitted: rmtree('%s')\n" % clean_dir) + return 1 + else: + raise - try: - if ("ccache" in features): - if (not mysettings.has_key("CCACHE_DIR")) or (mysettings["CCACHE_DIR"]==""): - mysettings["CCACHE_DIR"]=mysettings["PORTAGE_TMPDIR"]+"/ccache" - if not os.path.exists(mysettings["CCACHE_DIR"]): - os.makedirs(mysettings["CCACHE_DIR"]) - mystat = os.stat(mysettings["CCACHE_DIR"]) - if ("userpriv" in features): - if mystat[stat.ST_UID] != portage_uid or ((mystat[stat.ST_MODE]&02070)!=02070): - writemsg("* Adjusting permissions on ccache in %s\n" % mysettings["CCACHE_DIR"]) - spawn("chgrp -R "+str(portage_gid)+" "+mysettings["CCACHE_DIR"], mysettings, free=1) - spawn("chown "+str(portage_uid)+":"+str(portage_gid)+" "+mysettings["CCACHE_DIR"], mysettings, free=1) - spawn("chmod -R ug+rw "+mysettings["CCACHE_DIR"], mysettings, free=1) - spawn("find "+mysettings["CCACHE_DIR"]+" -type d -exec chmod g+xs \{\} \;", mysettings, free=1) + def makedirs(dir_path): + try: + os.makedirs(dir_path) + except OSError, oe: + if errno.EEXIST == oe.errno: + pass + elif errno.EPERM == oe.errno: + writemsg("%s\n" % oe) + writemsg("Operation Not Permitted: makedirs('%s')\n" % dir_path) + return False else: - if mystat[stat.ST_UID] != 0 or ((mystat[stat.ST_MODE]&02070)!=02070): - writemsg("* Adjusting permissions on ccache in %s\n" % mysettings["CCACHE_DIR"]) - spawn("chgrp -R "+str(portage_gid)+" "+mysettings["CCACHE_DIR"], mysettings, free=1) - spawn("chown 0:"+str(portage_gid)+" "+mysettings["CCACHE_DIR"], mysettings, free=1) - spawn("chmod -R ug+rw "+mysettings["CCACHE_DIR"], mysettings, free=1) - spawn("find "+mysettings["CCACHE_DIR"]+" -type d -exec chmod g+xs \{\} \;", mysettings, free=1) - except OSError, e: - print "!!! File system problem. (ReadOnly? Out of space?)" - print "!!! Perhaps: rm -Rf",mysettings["BUILD_PREFIX"] - print "!!!",str(e) - return 1 + raise + return True + + dir_mode_map = { + "BUILD_PREFIX" :00070, + "HOME" :02070, + "PORTAGE_BUILDDIR" :00070, + "PKG_LOGDIR" :00070, + "T" :02070 + } + + mysettings["PKG_LOGDIR"] = os.path.join(mysettings["T"], "logging") + + for dir_key, mode in dir_mode_map.iteritems(): + if not makedirs(mysettings[dir_key]): + return 1 + try: + apply_secpass_permissions(mysettings[dir_key], + gid=portage_gid, mode=mode, mask=02) + except portage_exception.OperationNotPermitted, e: + writemsg("Operation Not Permitted: %s\n" % str(e)) + return 1 + except portage_exception.FileNotFound, e: + writemsg("File Not Found: '%s'\n" % str(e)) + return 1 + + if "ccache" in features: + ccache_enabled = True + if "CCACHE_DIR" not in mysettings or "" == mysettings["CCACHE_DIR"]: + mysettings["CCACHE_DIR"] = os.path.join(mysettings["PORTAGE_TMPDIR"], "ccache") + + ccache_enabled = makedirs(mysettings["CCACHE_DIR"]) + + if ccache_enabled: + ccache_enabled = apply_recursive_permissions( + mysettings["CCACHE_DIR"], gid=portage_gid, + dirmode=02070, dirmask=02, + filemode=060, filemask=02) + + if not ccache_enabled: + writemsg("!!! Failed resetting perms on CCACHE_DIR='%s'\n" % mysettings["CCACHE_DIR"]) + features.remove("ccache") + mysettings["FEATURES"] = " ".join(features) + + del ccache_enabled if "confcache" in features: confcache_enabled = True if "CONFCACHE_DIR" not in mysettings: mysettings["CONFCACHE_DIR"] = os.path.join(mysettings["PORTAGE_TMPDIR"], "confcache") - confcache_dir_mode = 0775 - - try: - os.makedirs(mysettings["CONFCACHE_DIR"], mode=confcache_dir_mode) - except OSError, oe: - if oe.errno == errno.EEXIST: - pass - elif errno == errno.EPERM: - writemsg("Operation Not Permitted: makedirs(%s, mode=%s)\n" % (mysettings["CONFCACHE_DIR"], oct(confcache_dir_mode))) - confcache_enabled = False - - if confcache_enabled: - try: - confcache_enabled = apply_secpass_permissions( - mysettings["CONFCACHE_DIR"], - gid=portage_gid, mode=confcache_dir_mode) - except portage_exception.OperationNotPermitted, e: - writemsg("Operation Not Permitted: %s\n" % str(e)) - confcache_enabled = False - del confcache_dir_mode + confcache_enabled = makedirs(mysettings["CONFCACHE_DIR"]) if confcache_enabled: - for x in listdir(mysettings["CONFCACHE_DIR"]): - cache_file = os.path.join(mysettings["CONFCACHE_DIR"], x) - try: - confcache_enabled = apply_secpass_permissions(cache_file, gid=portage_gid, mode=0660, mask=07000) - except portage_exception.OperationNotPermitted, e: - writemsg("Operation Not Permitted: %s\n" % str(e)) - confcache_enabled = False - except portage_exception.FileNotFound, e: - writemsg("File Not Found: %s\n" % str(e)) + confcache_enabled = apply_recursive_permissions( + mysettings["CONFCACHE_DIR"], gid=portage_gid, + dirmode=02070, dirmask=02, + filemode=060, filemask=02) if not confcache_enabled: writemsg("!!! Failed resetting perms on confcachedir %s\n" % mysettings["CONFCACHE_DIR"]) features.remove("confcache") mysettings["FEATURES"] = " ".join(features) + del confcache_enabled + if "distcc" in features: distcc_enabled = True @@ -2629,24 +2593,15 @@ def prepare_build_dirs(myroot, mysettings, cleanup): mysettings["DISTCC_DIR"] = os.path.join(mysettings["BUILD_PREFIX"], ".distcc") for x in ("", "lock", "state"): mydir = os.path.join(mysettings["DISTCC_DIR"], x) - try: - os.makedirs(mydir) - except OSError, oe: - if errno.EEXIST == oe.errno: - pass - elif errno.EPERM == oe.errno: - distcc_enabled = False - break - else: - raise - try: - distcc_enabled = apply_secpass_permissions(mydir, - uid=portage_uid, gid=portage_gid, mode=02775) - except portage_exception.OperationNotPermitted, e: - writemsg("Operation Not Permitted: %s\n" % str(e)) + if not makedirs(mydir): distcc_enabled = False break + if distcc_enabled: + distcc_enabled = apply_recursive_permissions( + mysettings["DISTCC_DIR"], gid=portage_gid, + dirmode=02070, dirmask=02, filemode=060, filemask=02) + if not distcc_enabled: writemsg("\n!!! File system problem when setting DISTCC_DIR directory permissions.\n") writemsg( "!!! DISTCC_DIR="+str(mysettings["DISTCC_DIR"]+"\n")) @@ -2657,15 +2612,18 @@ def prepare_build_dirs(myroot, mysettings, cleanup): workdir_mode = 0700 try: - workdir_mode = int(eval(mysettings["PORTAGE_WORKDIR_MODE"])) - if workdir_mode & 07777 != workdir_mode: + parsed_mode = int(eval(mysettings["PORTAGE_WORKDIR_MODE"])) + if parsed_mode & 07777 != parsed_mode: raise ValueError("Invalid file mode: %s" % mysettings["PORTAGE_WORKDIR_MODE"]) + else: + workdir_mode = parsed_mode except KeyError, e: writemsg("!!! PORTAGE_WORKDIR_MODE is unset, using %s." % oct(workdir_mode)) - except ValueError, e: + except (ValueError, SyntaxError), e: writemsg("%s\n" % e) writemsg("!!! Unable to parse PORTAGE_WORKDIR_MODE='%s', using %s.\n" % \ (mysettings["PORTAGE_WORKDIR_MODE"], oct(workdir_mode))) + mysettings["PORTAGE_WORKDIR_MODE"] = oct(workdir_mode) try: apply_secpass_permissions(mysettings["WORKDIR"], uid=portage_uid, gid=portage_gid, mode=workdir_mode) @@ -2675,17 +2633,9 @@ def prepare_build_dirs(myroot, mysettings, cleanup): if "PORT_LOGDIR" in mysettings: logging_enabled = True - try: - os.makedirs(mysettings["PORT_LOGDIR"]) - except OSError, oe: - if errno.EEXIST == oe.errno: - pass - elif errno.EPERM == oe.errno: - writemsg("!!! Unable to create PORT_LOGDIR\n") - writemsg("!!! %s\n" % str(oe)) - logging_enabled = False - else: - raise + if not makedirs(mysettings["PORT_LOGDIR"]): + writemsg("!!! Unable to create PORT_LOGDIR\n") + logging_enabled = False if logging_enabled: try: @@ -2840,18 +2790,14 @@ def doebuild(myebuild,mydo,myroot,mysettings,debug=0,listonly=0,fetchonly=0,clea try: apply_secpass_permissions(mysettings["DISTDIR"], gid=portage_gid, mode=0775, mask=02) - cvs_src_dir = os.path.join(mysettings["DISTDIR"], "cvs-src") - apply_secpass_permissions(cvs_src_dir, - gid=portage_gid, mode=02770, mask=02) - portage_exec.spawn(["chgrp", "-R", str(portage_gid), cvs_src_dir]) - portage_exec.spawn(["chmod", "-R", "g+rw", cvs_src_dir]) - portage_exec.spawn(["find", cvs_src_dir, "-type", "d", - "-exec","chmod", "g+xs", "{}", ";"]) except portage_exception.OperationNotPermitted, e: writemsg("Operation Not Permitted: %s\n" % str(e)) except portage_exception.FileNotFound, e: writemsg("File Not Found: '%s'\n" % str(e)) + apply_recursive_permissions(os.path.join(mysettings["DISTDIR"], "cvs-src"), + gid=portage_gid, dirmode=02770, dirmask=02, filemode=0660, filemask=02) + # Only try and fetch the files if we are going to need them ... otherwise, # if user has FEATURES=noauto and they run `ebuild clean unpack compile install`, # we will try and fetch 4 times :/ diff --git a/pym/portage_util.py b/pym/portage_util.py index 9956b107d..aa84fa74e 100644 --- a/pym/portage_util.py +++ b/pym/portage_util.py @@ -2,7 +2,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/pym/portage_util.py,v 1.11.2.6 2005/04/23 07:26:04 jstubbs Exp $ -from portage_exception import FileNotFound, OperationNotPermitted +from portage_exception import PortageException, FileNotFound, OperationNotPermitted import sys,string,shlex,os,errno try: @@ -520,6 +520,47 @@ def apply_stat_permissions(filename, newstat, **kwargs): return apply_secpass_permissions(filename, uid=newstat.st_uid, gid=newstat.st_gid, mode=newstat.st_mode, **kwargs) +def apply_recursive_permissions(top, uid=-1, gid=-1, + dirmode=-1, dirmask=-1, filemode=-1, filemask=-1, onerror=None): + """A wrapper around apply_secpass_permissions that applies permissions + recursively. If optional argument onerror is specified, it should be a + function; it will be called with one argument, a PortageException instance. + Returns True if all permissions are applied and False if some are left + unapplied.""" + + if onerror is None: + # Default behavior is to dump errors to stderr so they won't + # go unnoticed. Callers can pass in a quiet instance. + def onerror(e): + if isinstance(e, OperationNotPermitted): + writemsg("Operation Not Permitted: %s\n" % str(e)) + elif isinstance(e, FileNotFound): + writemsg("File Not Found: '%s'\n" % str(e)) + else: + raise + + all_applied = True + for dirpath, dirnames, filenames in os.walk(top): + try: + applied = apply_secpass_permissions(dirpath, + uid=uid, gid=gid, mode=dirmode, mask=dirmask) + if not applied: + all_applied = False + except PortageException, e: + all_applied = False + onerror(e) + + for name in filenames: + try: + applied = apply_secpass_permissions(os.path.join(dirpath, name), + uid=uid, gid=gid, mode=filemode, mask=filemask) + if not applied: + all_applied = False + except PortageException, e: + all_applied = False + onerror(e) + return all_applied + def apply_secpass_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1, stat_cached=None): """A wrapper around apply_permissions that uses secpass and simple -- 2.26.2