From 1da867d28893e949fc1afccbe91f09cec2b6f479 Mon Sep 17 00:00:00 2001 From: Kito Date: Sun, 2 Apr 2006 02:03:49 +0000 Subject: [PATCH] merge from trunk rev 3030:3051 svn path=/main/branches/prefix/; revision=3052 --- bin/ebuild.sh | 2 +- bin/emerge | 6 +- cnf/make.globals | 4 +- pym/portage.py | 119 +++++++++++++++++++--------------------- pym/portage_debug.py | 9 ++- pym/portage_manifest.py | 8 ++- pym/portage_util.py | 42 +++++++++++++- 7 files changed, 111 insertions(+), 79 deletions(-) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 307339264..59aea5768 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -818,7 +818,7 @@ dyn_unpack() { local checkme for x in ${AA}; do echo ">>> Checking ${x}'s mtime..." - if [ "${DISTDIR}/${x}" -nt "${WORKDIR}" ]; then + if [ "${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}/${x}" -nt "${WORKDIR}" ]; then echo ">>> ${x} has been updated; recreating WORKDIR..." newstuff="yes" rm -rf "${WORKDIR}" diff --git a/bin/emerge b/bin/emerge index c945e7dd5..c46c599e1 100755 --- a/bin/emerge +++ b/bin/emerge @@ -154,9 +154,7 @@ def sorted_versions(verlist): if portage.settings.has_key("PORTAGE_NICENESS"): try: os.nice(int(portage.settings["PORTAGE_NICENESS"])) - except SystemExit, e: - raise # Needed else can't exit - except Exception,e: + except (OSError,ValueError), e: print "!!! Failed to change nice value to '"+str(portage.settings["PORTAGE_NICENESS"])+"'" print "!!!",e @@ -1721,7 +1719,7 @@ class depgraph: if "--columns" in myopts: if "--quiet" in myopts: myprint=addl+" "+indent+darkgreen(xs[0]) - myprint=myprint+" "+green(xs[1]+xs[2]) + myprint=myprint+" "+green(xs[1]+xs[2])+" " myprint=myprint+myoldbest else: myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0]) diff --git a/cnf/make.globals b/cnf/make.globals index a672d03a2..fe6528059 100644 --- a/cnf/make.globals +++ b/cnf/make.globals @@ -29,8 +29,8 @@ RPMDIR=@DOMAIN_PREFIX@/usr/portage/rpm PORTAGE_TMPDIR=@DOMAIN_PREFIX@/var/tmp # Fetching command (5 tries, passive ftp for firewall compatibility) -FETCHCOMMAND="@DOMAIN_PREFIX@/usr/bin/wget -t 5 --passive-ftp -P \${DISTDIR} \${URI}" -RESUMECOMMAND="@DOMAIN_PREFIX@/usr/bin/wget -c -t 5 --passive-ftp -P \${DISTDIR} \${URI}" +FETCHCOMMAND="wget -t 5 --passive-ftp -P \${DISTDIR} \${URI}" +RESUMECOMMAND="wget -c -t 5 --passive-ftp -P \${DISTDIR} \${URI}" # Default user options FEATURES="sandbox distlocks metadata-transfer" diff --git a/pym/portage.py b/pym/portage.py index b3518ebf1..fcf231f9d 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -505,7 +505,7 @@ endversion_keys = ["pre", "p", "alpha", "beta", "rc"] #parse /etc/env.d and generate /etc/profile.env -def env_update(makelinks=1): +def env_update(makelinks=1, srcroot=None): global root if not os.path.exists(root+portage_const.EPREFIX+"/etc/env.d"): prevmask=os.umask(0) @@ -618,22 +618,42 @@ def env_update(makelinks=1): if not mtimedb.has_key("ldpath"): mtimedb["ldpath"]={} - for x in map(lambda x: portage_const.EPREFIX+x, specials["LDPATH"]+['/usr/lib','/lib']): + for lib_dir in portage_util.unique_array(specials["LDPATH"]+['usr/lib','usr/lib64','usr/lib32','lib','lib64','lib32']): + x = os.path.join(normalize_path(root+portage_const.EPREFIX), lib_dir.lstrip(os.sep)) try: - newldpathtime=os.stat(x)[stat.ST_MTIME] - except SystemExit, e: + newldpathtime = os.stat(x)[stat.ST_MTIME] + except OSError, oe: + if oe.errno == errno.ENOENT: + try: + del mtimedb["ldpath"][x] + except KeyError: + pass + # ignore this path because it doesn't exist + continue raise - except: - newldpathtime=0 + mtime_changed = False if mtimedb["ldpath"].has_key(x): if mtimedb["ldpath"][x]==newldpathtime: pass else: mtimedb["ldpath"][x]=newldpathtime - ld_cache_update=True + mtime_changed = True else: mtimedb["ldpath"][x]=newldpathtime - ld_cache_update=True + mtime_changed = True + + if mtime_changed: + if srcroot is None: + ld_cache_update = True + continue + src_dir = os.path.join(srcroot, x.lstrip(os.sep)) + if not os.path.exists(src_dir): + ld_cache_update = True + continue + for parent_dir, dirs, files in os.walk(src_dir): + if len(files) > 0: + ld_cache_update = True + break # Only run ldconfig as needed if (ld_cache_update or makelinks): @@ -1841,29 +1861,12 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", print "!!! No write access to %s" % mysettings["DISTDIR"]+"/" can_fetch=False else: - def distdir_perms(filename): - all_applied = True - try: - all_applied = portage_util.apply_secpass_permissions(filename, gid=portage_gid, mode=0775) - except portage_exception.OperationNotPermitted: - all_applied = False - if not all_applied: - writemsg(("!!! Unable to apply group permissions to '%s'." \ - + " Non-root users may experience issues.\n") % filename) - distdir_perms(mysettings["DISTDIR"]) if use_locks and locks_in_subdir: distlocks_subdir = os.path.join(mysettings["DISTDIR"], locks_in_subdir) - try: - distdir_perms(distlocks_subdir) - except portage_exception.FileNotFound: - os.mkdir(distlocks_subdir) - distdir_perms(distlocks_subdir) if not os.access(distlocks_subdir, os.W_OK): writemsg("!!! No write access to write to %s. Aborting.\n" % distlocks_subdir) return 0 del distlocks_subdir - del distdir_perms - for myfile in filedict.keys(): fetched=0 file_lock = None @@ -2535,26 +2538,13 @@ def prepare_build_dirs(myroot, mysettings, cleanup): for subdir in kwargs["subdirs"]: mydirs.append(os.path.join(basedir, subdir)) for mydir in mydirs: - if not makedirs(mydir): - raise portage_exception.DirectoryNotFound( - "Failed to create directory.") - try: - initial_stat = os.stat(mydir) - apply_secpass_permissions(mydir, - gid=portage_gid, mode=dirmode, mask=modemask, stat_cached=initial_stat) - result_stat = os.stat(mydir) - except OSError, oe: - if errno.EPERM == oe.errno: - writemsg("!!! %s\n" % oe) - raise portage_exception.OperationNotPermitted("stat('%s')" % mydir) - raise + modified = portage_util.ensure_dirs(mydir, + gid=portage_gid, mode=dirmode, mask=modemask) # To avoid excessive recursive stat calls, we trigger # recursion when the top level directory does not initially # match our permission requirements. - if kwargs["always_recurse"] or \ - result_stat.st_gid != initial_stat.st_gid or \ - result_stat.st_mode & 07777 != initial_stat.st_mode & 07777: - if not kwargs["always_recurse"]: + if modified or kwargs["always_recurse"]: + if modified: writemsg("Adjusting permissions recursively: '%s'" % mydir) def onerror(e): raise # The feature is disabled if a single error @@ -2746,28 +2736,29 @@ def doebuild(myebuild,mydo,myroot,mysettings,debug=0,listonly=0,fetchonly=0,clea checkme=alist[:] if not listonly: - for x in ("", "cvs-src"): - mydir = os.path.join(mysettings["DISTDIR"], x) - try: - os.makedirs(mydir) - except OSError, oe: - if errno.EEXIST == oe.errno: - pass - elif errno.EPERM == oe.errno: - writemsg("!!! %s\n" % str(oe)) - writemsg("!!! Fetching may fail!\n") - else: - raise + dirmode = 02070 + filemode = 060 + modemask = 02 + distdir_dirs = ["", "cvs-src"] + if "distlocks" in features: + distdir_dirs.append(".locks") try: - apply_secpass_permissions(mysettings["DISTDIR"], - gid=portage_gid, mode=0775, mask=02) - 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) + + for x in distdir_dirs: + mydir = os.path.join(mysettings["DISTDIR"], x) + if portage_util.ensure_dirs(mydir, gid=portage_gid, mode=dirmode, mask=modemask): + writemsg("Adjusting permissions recursively: '%s'\n" % mydir) + def onerror(e): + raise # bail out on the first error that occurs during recursion + if not apply_recursive_permissions(mydir, + gid=portage_gid, dirmode=dirmode, dirmask=modemask, + filemode=filemode, filemask=modemask, onerror=onerror): + raise portage_exception.OperationNotPermitted( + "Failed to apply recursive permissions for the portage group.") + except portage_exception.PortageException, e: + writemsg("!!! %s\n" % str(e)) + writemsg("!!! Problem adjusting permissions on DISTDIR='%s'\n" % mysettings["DISTDIR"]) + writemsg("!!! Fetching may fail!\n") # 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`, @@ -6056,7 +6047,7 @@ class dblink: downgrade = True #update environment settings, library paths. DO NOT change symlinks. - env_update(makelinks=(not downgrade)) + env_update(makelinks=(not downgrade),srcroot=srcroot) #dircache may break autoclean because it remembers the -MERGING-pkg file global dircache if dircache.has_key(self.dbcatdir): diff --git a/pym/portage_debug.py b/pym/portage_debug.py index 318754d75..2ee8bcf28 100644 --- a/pym/portage_debug.py +++ b/pym/portage_debug.py @@ -19,15 +19,14 @@ def set_trace(on=True): class trace_handler(object): def __init__(self): - python_base = None + python_system_paths = [] for x in sys.path: if os.path.basename(x).startswith("python2."): - python_base = x - break + python_system_paths.append(x) self.ignore_prefixes = [] - if python_base is not None: - self.ignore_prefixes.append(python_base + os.sep) + for x in python_system_paths: + self.ignore_prefixes.append(x + os.sep) self.trim_filename = prefix_trimmer(os.path.join(portage_const.PORTAGE_BASE_PATH, "pym") + os.sep).trim self.show_local_lines = False diff --git a/pym/portage_manifest.py b/pym/portage_manifest.py index a9df1cc68..7803ff294 100644 --- a/pym/portage_manifest.py +++ b/pym/portage_manifest.py @@ -10,7 +10,13 @@ class FileNotInManifestException(PortageException): def manifest2AuxfileFilter(filename): filename = filename.strip(os.sep) - return not (filename in [".svn", "CVS"] or filename.startswith("CVS"+os.sep) or filename.startswith(".svn"+os.sep) or filename.startswith("digest-")) + for ignored_dir in ("CVS", ".bzr",".git",".svn"): + if filename == ignored_dir or \ + filename.startswith(ignored_dir+os.sep) or \ + filename.endswith(os.sep+ignored_dir) or \ + filename.find(os.sep+ignored_dir+os.sep)!=-1: + return False + return not filename.startswith("digest-") def manifest2MiscfileFilter(filename): filename = filename.strip(os.sep) diff --git a/pym/portage_util.py b/pym/portage_util.py index ae5312175..ae7525186 100644 --- a/pym/portage_util.py +++ b/pym/portage_util.py @@ -462,7 +462,10 @@ def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1, bits. When mask=0 is specified, mode bits on the target file are allowed to be a superset of the mode argument (via logical OR). When mask>0, the mode bits that the target file is allowed to have are restricted via - logical XOR.""" + logical XOR. + Returns True if the permissions were modified and False otherwise.""" + + modified = False if stat_cached is None: try: @@ -479,6 +482,7 @@ def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1, (gid != -1 and gid != stat_cached.st_gid): try: os.chown(filename, uid, gid) + modified = True except OSError, oe: if oe.errno == errno.EPERM: raise OperationNotPermitted("chown('%s', %i, %i)" % (filename, uid, gid)) @@ -506,6 +510,7 @@ def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1, if new_mode != -1: try: os.chmod(filename, new_mode) + modified = True except OSError, oe: if oe.errno == errno.EPERM: raise OperationNotPermitted("chmod('%s', %s)" % (filename, oct(new_mode))) @@ -513,6 +518,7 @@ def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1, raise FileNotFound(filename) else: raise + return modified def apply_stat_permissions(filename, newstat, **kwargs): """A wrapper around apply_secpass_permissions that gets @@ -607,9 +613,21 @@ class atomic_ofstream(file): file when the write is interrupted (for example, when an 'out of space' error occurs).""" - def __init__(self, filename, mode='w', **kargs): + def __init__(self, filename, mode='w', follow_links=True, **kargs): """Opens a temporary filename.pid in the same directory as filename.""" self._aborted = False + + if follow_links: + canonical_path = os.path.realpath(filename) + self._real_name = canonical_path + tmp_name = "%s.%i" % (canonical_path, os.getpid()) + try: + super(atomic_ofstream, self).__init__(tmp_name, mode=mode, **kargs) + return + except (OSError, IOError), e: + writemsg("!!! Failed to open file: '%s'\n" % tmp_name) + writemsg("!!! %s\n" % str(e)) + self._real_name = filename tmp_name = "%s.%i" % (filename, os.getpid()) super(atomic_ofstream, self).__init__(tmp_name, mode=mode, **kargs) @@ -668,3 +686,23 @@ def write_atomic(file_path, content): except IOError, ioe: f.abort() raise ioe + +def ensure_dirs(dir_path, *args, **kwargs): + """Create a directory and call apply_permissions. + Returns True if a directory is created or the permissions needed to be + modified, and False otherwise.""" + + created_dir = False + + try: + os.makedirs(dir_path) + created_dir = True + except OSError, oe: + if errno.EEXIST == oe.errno: + pass + elif oe.errno in (errno.EPERM, errno.EROFS): + raise portage_exception.OperationNotPermitted(str(oe)) + else: + raise + perms_modified = apply_permissions(dir_path, *args, **kwargs) + return created_dir or perms_modified -- 2.26.2