public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Zac Medico" <zmedico@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/portage:master commit in: bin/, pym/portage/
Date: Sat, 19 Jan 2013 03:23:14 +0000 (UTC)	[thread overview]
Message-ID: <1358564520.c7e110bae1ec05e9ecd745ac5cc7314006e5026c.zmedico@gentoo> (raw)

commit:     c7e110bae1ec05e9ecd745ac5cc7314006e5026c
Author:     Paul Varner <fuzzyray <AT> gentoo <DOT> org>
AuthorDate: Wed May 20 21:49:39 2009 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sat Jan 19 03:02:00 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=c7e110ba

Restructure system affection detection.

Store "vulnerable" and "upgrade" packages in a table, and use that
data to determine which packages cannot be upgraded, and which
packages actually cause upgrades

svn path=/trunk/gentoolkit/; revision=648

http://git.overlays.gentoo.org/gitweb/?p=proj/gentoolkit.git;a=commit;h=b6a2a23926d54ccfa9a1ce331c1bc97dbe2c73d1

---
 bin/glsa-check      |   72 ++++++++++++++++++++++++--------------------------
 pym/portage/glsa.py |   61 +++++++++++++++++++++++++++---------------
 2 files changed, 74 insertions(+), 59 deletions(-)

diff --git a/bin/glsa-check b/bin/glsa-check
index 969ad84..3cfe0ba 100644
--- a/bin/glsa-check
+++ b/bin/glsa-check
@@ -205,49 +205,47 @@ if mode in ["dump", "fix", "inject", "pretend"]:
 		if mode == "dump":
 			myglsa.dump()
 		elif mode == "fix":
-			sys.stdout.write("fixing "+myid+"\n")
-			mergelist = myglsa.getMergeList(least_change=least_change)
-			if mergelist == None:
+			sys.stdout.write("Fixing GLSA "+myid+"\n")
+			if not myglsa.isVulnerable():
 				sys.stdout.write(">>> no vulnerable packages installed\n")
-			elif mergelist == []:
-				sys.stdout.write(">>> cannot fix GLSA, no unaffected packages available\n")
-				sys.exit(2)
-			for pkg in mergelist:
-				sys.stdout.write(">>> merging "+pkg+"\n")
-				# using emerge for the actual merging as it contains the dependency
-				# code and we want to be consistent in behaviour. Also this functionality
-				# will be integrated in emerge later, so it shouldn't hurt much.
-				emergecmd = "emerge --oneshot " + portage.settings["EMERGE_OPTS"] + " =" + pkg
-				if verbose:
-					sys.stderr.write(emergecmd+"\n")
-				exitcode = os.system(emergecmd)
-				# system() returns the exitcode in the high byte of a 16bit integer
-				if exitcode >= 1<<8:
-					exitcode >>= 8
-				if exitcode:
-					sys.exit(exitcode)
+			else:
+				mergelist = myglsa.getMergeList(least_change=least_change)
+				if mergelist == []:
+					sys.stdout.write(">>> cannot fix GLSA, no unaffected packages available\n")
+					sys.exit(2)
+				for pkg in mergelist:
+					sys.stdout.write(">>> merging "+pkg+"\n")
+					# using emerge for the actual merging as it contains the dependency
+					# code and we want to be consistent in behaviour. Also this functionality
+					# will be integrated in emerge later, so it shouldn't hurt much.
+					emergecmd = "emerge --oneshot " + glsaconfig["EMERGE_OPTS"] + " =" + pkg
+					if verbose:
+						sys.stderr.write(emergecmd+"\n")
+					exitcode = os.system(emergecmd)
+					# system() returns the exitcode in the high byte of a 16bit integer
+					if exitcode >= 1<<8:
+						exitcode >>= 8
+					if exitcode:
+						sys.exit(exitcode)
+			if len(mergelist):
+				sys.stdout.write("\n")
 			myglsa.inject()
 		elif mode == "pretend":
 			sys.stdout.write("Checking GLSA "+myid+"\n")
-			mergelist = myglsa.getMergeList(least_change=least_change)
-			if mergelist == None:
+			if not myglsa.isVulnerable():
 				sys.stdout.write(">>> no vulnerable packages installed\n")
-			elif mergelist == []:
-				sys.stdout.write(">>> cannot fix GLSA, no unaffected packages available\n")
-				sys.exit(2)
-			if mergelist:
-				sys.stdout.write("The following updates will be performed for this GLSA:\n")
-				for pkg in mergelist:
-					oldver = None
-					for x in vardb.match(portage.cpv_getkey(pkg)):
-						if vardb._pkg_str(x, None).slot == portdb._pkg_str(pkg, None).slot:
-							oldver = x
-					if oldver == None:
-						raise ValueError("could not find old version for package %s" % pkg)
-					oldver = oldver[len(portage.cpv_getkey(oldver))+1:]
-					sys.stdout.write("     " + pkg + " (" + oldver + ")\n")
 			else:
-				sys.stdout.write("Nothing to do for this GLSA\n")
+				mergedict = {}
+				for (vuln, update) in myglsa.getAffectionTable(least_change=least_change):
+					mergedict.setdefault(update, []).append(vuln)
+				
+				sys.stdout.write(">>> The following updates will be performed for this GLSA:\n")
+				for pkg in mergedict:
+					if pkg != "":
+						sys.stdout.write("     " + pkg + " (vulnerable: " + ", ".join(mergedict[pkg]) + ")\n")
+				if "" in mergedict:
+					sys.stdout.write("\n>>> For the following packages, no upgrade path exists:\n")
+					sys.stdout.write("     " + ", ".join(mergedict[""]))
 		elif mode == "inject":
 			sys.stdout.write("injecting " + myid + "\n")
 			myglsa.inject()

diff --git a/pym/portage/glsa.py b/pym/portage/glsa.py
index 76eae2b..5cc735b 100644
--- a/pym/portage/glsa.py
+++ b/pym/portage/glsa.py
@@ -366,26 +366,36 @@ def getMinUpgrade(vulnerableList, unaffectedList, portdbapi, vardbapi, minimize=
 	v_installed = reduce(operator.add, [match(v, vardbapi) for v in vulnerableList], [])
 	u_installed = reduce(operator.add, [match(u, vardbapi) for u in unaffectedList], [])
 
-	install_unaffected = True
-	for i in v_installed:
-		if i not in u_installed:
-			install_unaffected = False
+	# remove all unaffected atoms from vulnerable list
+	v_installed = list(set(v_installed).difference(set(u_installed)))
 
-	if install_unaffected:
+	if not v_installed:
 		return None
 
+	# this tuple holds all vulnerable atoms, and the related upgrade atom
+	vuln_update = []
+	avail_updates = set()
 	for u in unaffectedList:
-		mylist = match(u, portdbapi, match_type="match-all")
-		for c in mylist:
-			i = best(v_installed)
-			if vercmp(c.version, i.version) > 0 \
-					and (rValue == "" \
-						or not match("="+rValue, portdbapi) \
-						or (minimize ^ (vercmp(c.version, rValue.version) > 0)) \
-							and match("="+c, portdbapi)) \
-					and portdbapi._pkg_str(c, None).slot == vardbapi._pkg_str(best(v_installed), None).slot:
-				rValue = c
-	return rValue
+		# TODO: This had match_type="match-all" before. I don't think it should
+		# since we disregarded masked items later anyway (match(=rValue, "porttree"))
+		avail_updates.update(match(u, "porttree"))
+	# if an atom is already installed, we should not consider it for upgrades
+	avail_updates.difference_update(u_installed)
+
+	for vuln in v_installed:
+		update = ""
+		for c in avail_updates:
+			c_pv = portage.catpkgsplit(c)
+			if vercmp(c.version, vuln.version) > 0 \
+					and (update == "" \
+						or (minimize ^ (vercmp(c.version, update.version) > 0))) \
+					and portdbapi._pkg_str(c, None).slot == vardbapi._pkg_str(vuln, None).slot:
+				update = c_pv[0]+"/"+c_pv[1]+"-"+c_pv[2]
+				if c_pv[3] != "r0":		# we don't like -r0 for display
+					update += "-"+c_pv[3]
+		vuln_update.append([vuln, update])
+
+	return vuln_update
 
 def format_date(datestr):
 	"""
@@ -692,11 +702,18 @@ class Glsa:
 		@rtype:		List of Strings
 		@return:	list of package-versions that have to be merged
 		"""
-		rValue = []
-		for pkg in self.packages:
+		return list(set(update for (vuln, update) in self.getAffectionTable(least_change) if update))
+
+	def getAffectionTable(self, least_change=True):
+		"""
+		Will initialize the self.systemAffection list of
+		atoms installed on the system that are affected
+		by this GLSA, and the atoms that are minimal upgrades.
+		"""
+		systemAffection = []
+		for pkg in self.packages.keys():
 			for path in self.packages[pkg]:
-				update = getMinUpgrade(path["vul_atoms"], path["unaff_atoms"], \
-					self.portdbapi, self.vardbapi, minimize=least_change)
+				update = getMinUpgrade(path["vul_atoms"], path["unaff_atoms"], minimize=least_change)
 				if update:
-					rValue.append(update)
-		return rValue
+					systemAffection.extend(update)
+		return systemAffection


             reply	other threads:[~2013-01-19  3:23 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-19  3:23 Zac Medico [this message]
  -- strict thread matches above, loose matches on Subject: below --
2014-11-17 17:43 [gentoo-commits] proj/portage:master commit in: bin/, pym/portage/ Zac Medico
2013-11-29 23:24 Mike Frysinger
2013-06-25  7:48 Zac Medico
2013-06-23 22:57 Zac Medico
2013-06-23 22:40 Zac Medico
2013-02-11  9:39 Zac Medico
2013-01-19  5:16 Zac Medico
2013-01-19  5:00 Zac Medico
2013-01-19  3:23 Zac Medico
2013-01-19  2:27 Zac Medico
2013-01-19  1:53 Zac Medico
2012-10-18  0:05 Zac Medico
2012-03-17 16:44 Zac Medico
2012-03-11  1:40 Mike Frysinger
2011-12-08  7:26 Zac Medico
2011-06-17 22:35 Zac Medico
2011-06-04  1:39 Zac Medico
2011-02-20  0:00 Zac Medico

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1358564520.c7e110bae1ec05e9ecd745ac5cc7314006e5026c.zmedico@gentoo \
    --to=zmedico@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox