summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--trunk/ChangeLog5
-rw-r--r--trunk/src/glsa-check/glsa-check26
-rw-r--r--trunk/src/glsa-check/glsa.py47
3 files changed, 57 insertions, 21 deletions
diff --git a/trunk/ChangeLog b/trunk/ChangeLog
index e150ce2..442a1a8 100644
--- a/trunk/ChangeLog
+++ b/trunk/ChangeLog
@@ -1,3 +1,8 @@
+2007-05-30: Marius Mauch <genone@gentoo.org>
+ * glsa-check: check SLOT when selecting and displaying upgrades
+ * glsa-check: new --emergelike option to use the best version
+ within the same SLOT instead of the one with the smallest delta.
+
2007-05-21: Paul Varner <fuzzyray@gentoo.org>
* echangelog: Add patch from genstef to fix issues from Bug 176337
diff --git a/trunk/src/glsa-check/glsa-check b/trunk/src/glsa-check/glsa-check
index 6d2a11b..5789547 100644
--- a/trunk/src/glsa-check/glsa-check
+++ b/trunk/src/glsa-check/glsa-check
@@ -17,7 +17,7 @@ from getopt import getopt,GetoptError
__program__ = "glsa-check"
__author__ = "Marius Mauch <genone@gentoo.org>"
-__version__ = "0.8"
+__version__ = "0.9"
optionmap = [
["-l", "--list", "list all unapplied GLSA"],
@@ -27,6 +27,7 @@ optionmap = [
["-f", "--fix", "try to auto-apply this GLSA (experimental)"],
["-i", "--inject", "inject the given GLSA into the checkfile"],
["-n", "--nocolor", "disable colors (option)"],
+["-e", "--emergelike", "do not use a least-change algorithm (option)"],
["-h", "--help", "show this help message"],
["-V", "--version", "some information about this tool"],
["-v", "--verbose", "print more information (option)"],
@@ -67,6 +68,12 @@ try:
if option in args:
list_cve = True
args.remove(option)
+
+ least_change = True
+ for option in ["--emergelike", "-e"]:
+ if option in args:
+ least_change = False
+ args.remove(option)
# sanity checking
if len(args) <= 0:
@@ -125,6 +132,9 @@ from glsa import *
glsaconfig = checkconfig(portage.config(clone=portage.settings))
+vardb = portage.db["/"]["vartree"].dbapi
+portdb = portage.db["/"]["porttree"].dbapi
+
# Check that we really have a glsa dir to work on
if not (os.path.exists(glsaconfig["GLSA_DIR"]) and os.path.isdir(glsaconfig["GLSA_DIR"])):
sys.stderr.write(red("ERROR")+": GLSA_DIR %s doesn't exist. Please fix this.\n" % glsaconfig["GLSA_DIR"])
@@ -203,7 +213,7 @@ def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
fd1.write("... ")
else:
for pkg in myglsa.packages.keys():
- mylist = portage.db["/"]["vartree"].dbapi.match(portage.dep_getkey(pkg))
+ mylist = vardb.match(portage.dep_getkey(pkg))
if len(mylist) > 0:
pkg = color(" ".join(mylist))
fd1.write(" " + pkg + " ")
@@ -230,7 +240,7 @@ if mode in ["dump", "fix", "inject", "pretend"]:
myglsa.dump()
elif mode == "fix":
sys.stdout.write("fixing "+myid+"\n")
- mergelist = myglsa.getMergeList()
+ mergelist = myglsa.getMergeList(least_change=least_change)
for pkg in mergelist:
sys.stdout.write(">>> merging "+pkg+"\n")
# using emerge for the actual merging as it contains the dependency
@@ -245,12 +255,16 @@ if mode in ["dump", "fix", "inject", "pretend"]:
myglsa.inject()
elif mode == "pretend":
sys.stdout.write("Checking GLSA "+myid+"\n")
- mergelist = myglsa.getMergeList()
+ mergelist = myglsa.getMergeList(least_change=least_change)
if mergelist:
sys.stdout.write("The following updates will be performed for this GLSA:\n")
for pkg in mergelist:
- # we simplify a bit here
- oldver = portage.db["/"]["vartree"].dbapi.match(portage.dep_getkey(pkg))[-1]
+ oldver = None
+ for x in vardb.match(portage.dep_getkey(pkg)):
+ if vardb.aux_get(x, ["SLOT"]) == portdb.aux_get(pkg, ["SLOT"]):
+ oldver = x
+ if oldver == None:
+ raise ValueError("could not find old version for package %s" % pkg)
oldver = oldver[len(portage.dep_getkey(oldver))+1:]
sys.stdout.write(" " + pkg + " (" + oldver + ")\n")
else:
diff --git a/trunk/src/glsa-check/glsa.py b/trunk/src/glsa-check/glsa.py
index 474f9f2..87a39e4 100644
--- a/trunk/src/glsa-check/glsa.py
+++ b/trunk/src/glsa-check/glsa.py
@@ -288,7 +288,7 @@ def makeVersion(versionNode):
return opMapping[versionNode.getAttribute("range")] \
+getText(versionNode, format="strip")
-def match(atom, portdbname):
+def match(atom, portdbname, match_type="default"):
"""
wrapper that calls revisionMatch() or portage.dbapi.match() depending on
the given atom.
@@ -297,16 +297,22 @@ def match(atom, portdbname):
@param atom: a <~ or >~ atom or a normal portage atom that contains the atom to match against
@type portdb: portage.dbapi
@param portdb: one of the portage databases to use as information source
+ @type match_type: string
+ @param match_type: if != "default" passed as first argument to dbapi.xmatch
+ to apply the wanted visibility filters
@rtype: list of strings
@return: a list with the matching versions
"""
+ db = portage.db["/"][portdbname].dbapi
if atom[2] == "~":
- return revisionMatch(atom, portage.db["/"][portdbname].dbapi)
+ return revisionMatch(atom, db, match_type=match_type)
+ elif match_type == "default" or not hasattr(db, "xmatch"):
+ return db.match(atom)
else:
- return portage.db["/"][portdbname].dbapi.match(atom)
+ return db.xmatch(match_type, atom)
-def revisionMatch(revisionAtom, portdb):
+def revisionMatch(revisionAtom, portdb, match_type="default"):
"""
handler for the special >~, >=~, <=~ and <~ atoms that are supposed to behave
as > and < except that they are limited to the same version, the range only
@@ -316,11 +322,17 @@ def revisionMatch(revisionAtom, portdb):
@param revisionAtom: a <~ or >~ atom that contains the atom to match against
@type portdb: portage.dbapi
@param portdb: one of the portage databases to use as information source
+ @type match_type: string
+ @param match_type: if != "default" passed as first argument to portdb.xmatch
+ to apply the wanted visibility filters
@rtype: list of strings
@return: a list with the matching versions
"""
- mylist = portdb.match(re.sub("-r[0-9]+$", "", revisionAtom[2:]))
+ if match_type == "default" or not hasattr(portdb, "xmatch"):
+ mylist = portdb.match(re.sub("-r[0-9]+$", "", revisionAtom[2:]))
+ else:
+ mylist = portdb.xmatch(match_type, re.sub("-r[0-9]+$", "", revisionAtom[2:]))
rValue = []
for v in mylist:
r1 = portage.pkgsplit(v)[-1][1:]
@@ -330,7 +342,7 @@ def revisionMatch(revisionAtom, portdb):
return rValue
-def getMinUpgrade(vulnerableList, unaffectedList):
+def getMinUpgrade(vulnerableList, unaffectedList, minimize=True):
"""
Checks if the systemstate is matching an atom in
I{vulnerableList} and returns string describing
@@ -344,6 +356,9 @@ def getMinUpgrade(vulnerableList, unaffectedList):
@param vulnerableList: atoms matching vulnerable package versions
@type unaffectedList: List of Strings
@param unaffectedList: atoms matching unaffected package versions
+ @type minimize: Boolean
+ @param minimize: True for a least-change upgrade, False for emerge-like algorithm
+
@rtype: String | None
@return: the lowest unaffected version that is greater than
the installed version.
@@ -363,22 +378,22 @@ def getMinUpgrade(vulnerableList, unaffectedList):
install_unaffected = False
if install_unaffected:
- return []
+ return rValue
for u in unaffectedList:
- if u[2] == "~":
- mylist = revisionMatch(u, portage.db["/"]["porttree"].dbapi)
- else:
- mylist = portage.db["/"]["porttree"].dbapi.xmatch("match-all", u)
+ mylist = match(u, "porttree", match_type="match-all")
for c in mylist:
c_pv = portage.catpkgsplit(c)
i_pv = portage.catpkgsplit(portage.best(v_installed))
- if portage.pkgcmp(c_pv[1:], i_pv[1:]) > 0 and (rValue == None or portage.pkgcmp(c_pv[1:], portage.catpkgsplit(rValue)[1:]) < 0):
+ if portage.pkgcmp(c_pv[1:], i_pv[1:]) > 0 \
+ and (rValue == None or (minimize ^ (portage.pkgcmp(c_pv[1:], portage.catpkgsplit(rValue)[1:]) > 0))) \
+ and portage.db["/"]["porttree"].dbapi.aux_get(c, ["SLOT"]) == portage.db["/"]["vartree"].dbapi.aux_get(portage.best(v_installed), ["SLOT"]):
rValue = c_pv[0]+"/"+c_pv[1]+"-"+c_pv[2]
if c_pv[3] != "r0": # we don't like -r0 for display
rValue += "-"+c_pv[3]
return rValue
+
# simple Exception classes to catch specific errors
class GlsaTypeException(Exception):
def __init__(self, doctype):
@@ -602,20 +617,22 @@ class Glsa:
checkfile.close()
return None
- def getMergeList(self):
+ def getMergeList(self, least_change=True):
"""
Returns the list of package-versions that have to be merged to
apply this GLSA properly. The versions are as low as possible
while avoiding downgrades (see L{getMinUpgrade}).
+ @type least_change: Boolean
+ @param least_change: True if the smallest possible upgrade should be selected,
+ False for an emerge-like algorithm
@rtype: List of Strings
@return: list of package-versions that have to be merged
"""
rValue = []
for pkg in self.packages.keys():
for path in self.packages[pkg]:
- update = getMinUpgrade(path["vul_atoms"],
- path["unaff_atoms"])
+ update = getMinUpgrade(path["vul_atoms"], path["unaff_atoms"], minimize=least_change)
if update:
rValue.append(update)
return rValue