From 68eb72e3bb80f39939d7a97ecaf6896f6d98d96c Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sat, 17 Jan 2009 16:56:19 +0000 Subject: [PATCH] Merged from trunk -r12492:12520 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit | 12494 | Simplify depgraph._select_pkg_from_graph() by using | | zmedico | match_pkgs(). | | 12495 | Bug #254860 - Inside _expand_new_virtuals(), generate | | zmedico | instances of Atom instead of plain strings, so calling code | | | can assume that only Atom instances will be returned when | | | strict mode is enabled. | | 12496 | Use a new 'usersync' feature to control dropping of | | zmedico | privileges for --sync, since it's fairly common for people | | | to have inconsistent permissions between $PORTDIR and | | | contained files/directories. | | 12497 | Bug #254860 - Add another missing str -> atom conversion | | zmedico | inside _expand_new_virtuals(). | | 12498 | Bug #254825 - Improve messages that are displayed when | | zmedico | manifest generation bails out due to a changed distfile | | | digest. | | 12499 | Inside digestgen(), don't unnecessarily call fetch() in | | zmedico | cases when the there are no hashes for comparison and the | | | file already exists in $DISTDIR. | | 12500 | Bug #254825 - Add a note about the need to use `ebuild | | zmedico | --force manifest` to update distfiles digests. | | 12501 | In spawn(), put the full cpv in opt_name, instead of just | | zmedico | $PF. Thanks to Diego Pettenò for the | | | suggestion. | | 12502 | Make sure spawn() always initializes opt_name because later | | zmedico | code assumes that it is. | | 12503 | Add some more variables to config._env_blacklist to ensure | | zmedico | that they never leak in from the calling environment. | | 12514 | Fix repoman conditionals inside _expand_new_virtuals() to | | zmedico | use config.local_config instead of checking for portdbapi | | | type. | | 12518 | Don't show the running Linux kernel version in the commit | | zmedico | message, since it might leak information that would be | | | useful to attackers. Thanks to Ned Ludd for the | | | suggestion. | | 12519 | Drop the kernel version from the commit message for all | | zmedico | platforms. Thanks to Fabian Groffen for the | | | suggestion. | | 12520 | Call depgraph._set_args() inside _load_favorites(), to | | zmedico | eliminate duplicate code. | svn path=/main/branches/prefix/; revision=12526 --- RELEASE-NOTES | 5 +++ bin/repoman | 2 +- man/make.conf.5 | 4 ++ pym/_emerge/__init__.py | 40 ++++--------------- pym/portage/__init__.py | 87 ++++++++++++++++++++++++++++++----------- 5 files changed, 81 insertions(+), 57 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index b68c02d90..c5a5dc6c2 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -47,6 +47,11 @@ portage-2.1.6 used in ACCEPT_KEYWORDS. For packages that don't specify any other KEYWORDS you can use the new ** token as documented in portage(5) to disable KEYWORDS filtering completely. +* When generating manifests, existing distfiles digests will not be updated + in cases when the current file in $DISTDIR does not match. In order to + force digests to be updated, run `ebuild --force manifest`. + This is a safety measure which protects valid distfiles digests from being + accidentally replaced by invalid digests. portage-2.1.5 ================================== diff --git a/bin/repoman b/bin/repoman index dc1bbd6c7..c788f1f68 100755 --- a/bin/repoman +++ b/bin/repoman @@ -1894,7 +1894,7 @@ else: sys.stderr.write("Failed to insert portage version in message!\n") sys.stderr.flush() portage_version = "Unknown" - unameout = platform.system() + " " + platform.release() + " " + unameout = platform.system() + " " if platform.system() in ["Darwin", "SunOS"]: unameout += platform.processor() else: diff --git a/man/make.conf.5 b/man/make.conf.5 index 9a0261e25..83b7fa3ba 100644 --- a/man/make.conf.5 +++ b/man/make.conf.5 @@ -360,6 +360,10 @@ portage:portage without a sandbox (unless \fIusersandbox\fR is also used). .B usersandbox Enable the sandbox in the compile phase, when running without root privs (\fIuserpriv\fR). .TP +.B usersync +Drop privileges to the owner of \fBPORTDIR\fR for \fBemerge(1) --sync\fR +operations. +.TP .B webrsync-gpg Enable GPG verification when using \fIemerge\-webrsync\fR. .RE diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index bc7e3ecc7..711418eb3 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -6265,19 +6265,12 @@ class depgraph(object): replacement. """ graph_db = self._graph_trees[root]["porttree"].dbapi - matches = graph_db.match(atom) + matches = graph_db.match_pkgs(atom) if not matches: return None, None - cpv = matches[-1] # highest match - slot_atom = "%s:%s" % (portage.cpv_getkey(cpv), - graph_db.aux_get(cpv, ["SLOT"])[0]) - e_pkg = self._slot_pkg_map[root].get(slot_atom) - if e_pkg: - return e_pkg, e_pkg - # Since this cpv exists in the graph_db, - # we must have a cached Package instance. - cache_key = ("installed", root, cpv, "nomerge") - return (self._pkg_cache[cache_key], None) + pkg = matches[-1] # highest match + in_graph = self._slot_pkg_map[root].get(pkg.slot_atom) + return pkg, in_graph def _complete_graph(self): """ @@ -8610,27 +8603,7 @@ class depgraph(object): args.append(AtomArg(arg=x, atom=x, root_config=root_config)) - # Create the "args" package set from atoms and - # packages given as arguments. - args_set = self._sets["args"] - for arg in args: - if not isinstance(arg, (AtomArg, PackageArg)): - continue - myatom = arg.atom - if myatom in args_set: - continue - args_set.add(myatom) - self._set_atoms.update(chain(*self._sets.itervalues())) - atom_arg_map = self._atom_arg_map - for arg in args: - for atom in arg.set: - atom_key = (atom, arg.root_config.root) - refs = atom_arg_map.get(atom_key) - if refs is None: - refs = [] - atom_arg_map[atom_key] = refs - if arg not in refs: - refs.append(arg) + self._set_args(args) return args class UnsatisfiedResumeDep(portage.exception.PortageException): @@ -12117,7 +12090,8 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): spawn_kwargs = {} spawn_kwargs["env"] = settings.environ() - if portage.data.secpass >= 2 and \ + if 'usersync' in settings.features and \ + portage.data.secpass >= 2 and \ (st.st_uid != os.getuid() and st.st_mode & 0700 or \ st.st_gid != os.getgid() and st.st_mode & 0070): try: diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index d6aae6b69..98ab4594e 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -916,9 +916,12 @@ class config(object): """ _env_blacklist = [ - "A", "AA", "CATEGORY", "EBUILD_PHASE", "EMERGE_FROM", - "PF", "PKGUSE", "PORTAGE_CONFIGROOT", "PORTAGE_IUSE", - "PORTAGE_REPO_NAME", "PORTAGE_USE", "ROOT", "EPREFIX", "EROOT" + "A", "AA", "CATEGORY", "DEPEND", "DESCRIPTION", "EAPI", + "EBUILD_PHASE", "EMERGE_FROM", "HOMEPAGE", "INHERITED", "IUSE", + "KEYWORDS", "LICENSE", "PDEPEND", "PF", "PKGUSE", + "PORTAGE_CONFIGROOT", "PORTAGE_IUSE", "PORTAGE_REPO_NAME", + "PORTAGE_USE", "PROPERTIES", "PROVIDE", "RDEPEND", "RESTRICT", + "ROOT", "SLOT", "SRC_URI", "EPREFIX", "EROOT" ] _environ_whitelist = [] @@ -3052,7 +3055,11 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero else: check_config_instance(mysettings) env=mysettings.environ() - keywords["opt_name"]="[%s]" % mysettings["PF"] + if mysettings.mycpv is not None: + keywords["opt_name"] = "[%s]" % mysettings.mycpv + else: + keywords["opt_name"] = "[%s/%s]" % \ + (mysettings.get("CATEGORY",""), mysettings.get("PF","")) fd_pipes = keywords.get("fd_pipes") if fd_pipes is None: @@ -3940,12 +3947,23 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", if not can_fetch: if fetched != 2: - if fetched == 0: + try: + mysize = os.stat(myfile_path).st_size + except OSError, e: + if e.errno != errno.ENOENT: + raise + del e + mysize = 0 + + if mysize == 0: writemsg("!!! File %s isn't fetched but unable to get it.\n" % myfile, noiselevel=-1) - else: + elif size is None or size > mysize: writemsg("!!! File %s isn't fully fetched, but unable to complete it\n" % myfile, noiselevel=-1) + else: + writemsg(("!!! File %s is incorrect size, " + \ + "but unable to retry.\n") % myfile, noiselevel=-1) for var_name in ("FETCHCOMMAND", "RESUMECOMMAND"): if not mysettings.get(var_name, None): writemsg(("!!! %s is unset. It should " + \ @@ -4252,7 +4270,12 @@ def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None for myfile in distfiles_map: myhashes = dist_hashes.get(myfile) if not myhashes: - missing_files.append(myfile) + try: + st = os.stat(os.path.join(mysettings["DISTDIR"], myfile)) + except OSError: + st = None + if st is None or st.st_size == 0: + missing_files.append(myfile) continue size = myhashes.get("size") @@ -4279,7 +4302,7 @@ def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None fetch_settings = config(clone=mysettings) debug = mysettings.get("PORTAGE_DEBUG") == "1" for myfile in missing_files: - success = False + uris = set() for cpv in distfiles_map[myfile]: myebuild = os.path.join(mysettings["O"], catsplit(cpv)[1] + ".ebuild") @@ -4287,15 +4310,33 @@ def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None doebuild_environment(myebuild, "fetch", mysettings["ROOT"], fetch_settings, debug, 1, myportdb) - uri_map = myportdb.getFetchMap(cpv, mytree=mytree) - myuris = {myfile:uri_map[myfile]} - fetch_settings["A"] = myfile # for use by pkg_nofetch() - if fetch(myuris, fetch_settings): - success = True - break - if not success: - writemsg(("!!! File %s doesn't exist, can't update " + \ + uris.update(myportdb.getFetchMap( + cpv, mytree=mytree)[myfile]) + + fetch_settings["A"] = myfile # for use by pkg_nofetch() + + try: + st = os.stat(os.path.join( + mysettings["DISTDIR"],myfile)) + except OSError: + st = None + + if not fetch({myfile : uris}, fetch_settings): + writemsg(("!!! Fetch failed for %s, can't update " + \ "Manifest\n") % myfile, noiselevel=-1) + if myfile in dist_hashes and \ + st is not None and st.st_size > 0: + # stat result is obtained before calling fetch(), + # since fetch may rename the existing file if the + # digest does not match. + writemsg("!!! If you would like to " + \ + "forcefully replace the existing " + \ + "Manifest entry\n!!! for %s, use the " % \ + myfile + "following command:\n" + \ + "!!! " + colorize("INFORM", + "ebuild --force %s manifest" % \ + os.path.basename(myebuild)) + "\n", + noiselevel=-1) return 0 writemsg_stdout(">>> Creating Manifest for %s\n" % mysettings["O"]) try: @@ -6308,7 +6349,7 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", # for new-style virtuals. Repoman should enforce this. dep_keys = ["RDEPEND", "DEPEND", "PDEPEND"] portdb = trees[myroot]["porttree"].dbapi - repoman = isinstance(mydbapi, portdbapi) + repoman = not mysettings.local_config if kwargs["use_binaries"]: portdb = trees[myroot]["bintree"].dbapi myvirtuals = mysettings.getvirtuals() @@ -6380,7 +6421,7 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", newsplit.append(x) continue if not pkgs and len(mychoices) == 1: - newsplit.append(x.replace(mykey, mychoices[0])) + newsplit.append(portage.dep.Atom(x.replace(mykey, mychoices[0]))) continue if isblocker: a = [] @@ -6390,8 +6431,7 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", cpv, pv_split, db = y depstring = " ".join(db.aux_get(cpv, dep_keys)) pkg_kwargs = kwargs.copy() - if isinstance(db, portdbapi): - # for repoman + if repoman: pass else: # for emerge @@ -6411,13 +6451,14 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", if len(virtual_atoms) == 1: # It wouldn't make sense to block all the components of a # compound virtual, so only a single atom block is allowed. - a.append("!" + virtual_atoms[0]) + a.append(portage.dep.Atom("!" + virtual_atoms[0])) else: - mycheck[1].append("="+y[0]) # pull in the new-style virtual + # pull in the new-style virtual + mycheck[1].append(portage.dep.Atom("="+y[0])) a.append(mycheck[1]) # Plain old-style virtuals. New-style virtuals are preferred. for y in mychoices: - a.append(x.replace(mykey, y)) + a.append(portage.dep.Atom(x.replace(mykey, y, 1))) if isblocker and not a: # Probably a compound virtual. Pass the atom through unprocessed. newsplit.append(x) -- 2.26.2