[yum] Massive hack for Fedora/updateinfo stable vs. testing statuses. BZ 960642.
James Antill
james at fedoraproject.org
Wed May 8 18:24:24 UTC 2013
commit 24df1fd895c85a4da42be1f94cb353c297b07181
Author: James Antill <james at and.org>
Date: Wed May 8 14:24:17 2013 -0400
Massive hack for Fedora/updateinfo stable vs. testing statuses. BZ 960642.
- Don't load updateinfo when we don't have to.
- Tell which repo. we are skipping the updateinfo notice from.
- Compat. code so we can treat groups/igroups the same. BZ 955236.
- Don't highlight the empty space, Eg. --showdups list.
yum-3.4.3-comps.patch | 15 ----
yum-HEAD.patch | 174 ++++++++++++++++++++++++++++++++++++-------------
yum.spec | 11 ++-
3 files changed, 136 insertions(+), 64 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index 00573c9..c602cce 100644
--- a/yum-HEAD.patch
+++ b/yum-HEAD.patch
@@ -4519,7 +4519,7 @@ index f1e06e8..b319963 100644
complete -F _yum -o filenames yum yummain.py
diff --git a/output.py b/output.py
-index b6aa277..e17194c 100755
+index b6aa277..6b9e9e2 100755
--- a/output.py
+++ b/output.py
@@ -1,6 +1,6 @@
@@ -4861,6 +4861,18 @@ index b6aa277..e17194c 100755
total_width = len(msg)
data = []
for col_data in columns[:-1]:
+@@ -495,9 +689,9 @@ class YumOutput:
+ # we can.
+ msg += u"%s%s%s%s "
+ if (align == u'-'):
+- data.extend([hibeg, val, " " * (width - val_width), hiend])
++ data.extend([hibeg, val, hiend, " " * (width - val_width)])
+ else:
+- data.extend([hibeg, " " * (width - val_width), val, hiend])
++ data.extend([" " * (width - val_width), hibeg, val, hiend])
+ else:
+ msg += u"%s%s%s\n" + " " * (total_width + width + 1)
+ data.extend([hibeg, val, hiend])
@@ -513,8 +707,18 @@ class YumOutput:
def simpleList(self, pkg, ui_overflow=False, indent='', highlight=False,
@@ -190378,7 +190390,7 @@ index 7ad25ce..a9a8e53 100644
pass
diff --git a/yum/comps.py b/yum/comps.py
-index 65f6d5e..d2deb4a 100755
+index 65f6d5e..b9c6202 100755
--- a/yum/comps.py
+++ b/yum/comps.py
@@ -16,14 +16,14 @@
@@ -190425,7 +190437,7 @@ index 65f6d5e..d2deb4a 100755
self.groupid = None
self.display_order = 1024
self.installed = False
-@@ -271,6 +281,152 @@ class Group(CompsObj):
+@@ -271,6 +281,155 @@ class Group(CompsObj):
return msg
@@ -190521,7 +190533,10 @@ index 65f6d5e..d2deb4a 100755
+ optionid = child.text
+ self._options[optionid] = 1
+ defopt = child.attrib.get('default')
-+ default = parse_boolean(defopt)
++ if defopt:
++ default = parse_boolean(defopt)
++ else:
++ default = False
+ if default:
+ self._defaultoptions[optionid] = 1
+
@@ -190578,7 +190593,7 @@ index 65f6d5e..d2deb4a 100755
class Category(CompsObj):
""" Category object parsed from group data in each repo. and merged. """
-@@ -371,12 +527,61 @@ class Category(CompsObj):
+@@ -371,12 +530,61 @@ class Category(CompsObj):
msg += """ </category>\n"""
return msg
@@ -190641,7 +190656,7 @@ index 65f6d5e..d2deb4a 100755
self.compscount = 0
self.overwrite_groups = overwrite_groups
self.compiled = False # have groups been compiled into avail/installed
-@@ -387,14 +592,24 @@ class Comps(object):
+@@ -387,14 +595,24 @@ class Comps(object):
grps = self._groups.values()
grps.sort(key=lambda x: (x.display_order, x.name))
return grps
@@ -190667,7 +190682,7 @@ index 65f6d5e..d2deb4a 100755
def has_group(self, grpid):
exists = self.return_groups(grpid)
-@@ -447,6 +662,57 @@ class Comps(object):
+@@ -447,6 +665,57 @@ class Comps(object):
return returns.values()
@@ -190725,7 +190740,7 @@ index 65f6d5e..d2deb4a 100755
# This is close to returnPackages() etc. API ... need to std. these names
# the above return_groups uses different, but equal, API.
def return_categories(self, pattern, ignore_case=True):
-@@ -490,6 +756,13 @@ class Comps(object):
+@@ -490,6 +759,13 @@ class Comps(object):
else:
self._groups[group.groupid] = group
@@ -190739,7 +190754,7 @@ index 65f6d5e..d2deb4a 100755
def add_category(self, category):
if category.categoryid in self._categories:
thatcat = self._categories[category.categoryid]
-@@ -497,6 +770,9 @@ class Comps(object):
+@@ -497,6 +773,9 @@ class Comps(object):
else:
self._categories[category.categoryid] = category
@@ -190749,7 +190764,7 @@ index 65f6d5e..d2deb4a 100755
def add(self, srcfile = None):
if not srcfile:
raise CompsException
-@@ -520,9 +796,14 @@ class Comps(object):
+@@ -520,9 +799,14 @@ class Comps(object):
if elem.tag == "group":
group = Group(elem)
self.add_group(group)
@@ -190764,7 +190779,7 @@ index 65f6d5e..d2deb4a 100755
except SyntaxError, e:
raise CompsException, "comps file is empty/damaged"
-@@ -557,13 +838,32 @@ class Comps(object):
+@@ -557,13 +841,32 @@ class Comps(object):
if pkgname in inst_pkg_names:
group.installed = True
break
@@ -190798,7 +190813,7 @@ index 65f6d5e..d2deb4a 100755
return ""
msg = """<?xml version="1.0" encoding="UTF-8"?>
-@@ -575,7 +875,9 @@ class Comps(object):
+@@ -575,7 +878,9 @@ class Comps(object):
msg += g.xml()
for c in self.get_categories():
msg += c.xml()
@@ -190809,7 +190824,7 @@ index 65f6d5e..d2deb4a 100755
msg += """\n</comps>\n"""
return msg
-@@ -590,16 +892,34 @@ def main():
+@@ -590,16 +895,34 @@ def main():
for srcfile in sys.argv[1:]:
p.add(srcfile)
@@ -193485,10 +193500,10 @@ index 9889bf6..76a258d 100755
Setup the yum translation domain and make _() and P_() translation wrappers
diff --git a/yum/igroups.py b/yum/igroups.py
new file mode 100644
-index 0000000..467aa7b
+index 0000000..17f1b56
--- /dev/null
+++ b/yum/igroups.py
-@@ -0,0 +1,268 @@
+@@ -0,0 +1,279 @@
+#! /usr/bin/python -tt
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
@@ -193531,6 +193546,12 @@ index 0000000..467aa7b
+ pkg_names = set(pkg_names)
+ return sorted(pkg_names.difference(self.pkg_names))
+
++ groupid = property(fget=lambda self: self.gid,
++ fset=lambda self, value: setattr(self, "gid", value),
++ fdel=lambda self: setattr(self, "gid", None),
++ doc="Compat. to treat comps groups/igroups the same")
++
++
+
+class InstalledEnvironment(object):
+ def __init__(self, evgid):
@@ -193550,6 +193571,11 @@ index 0000000..467aa7b
+ grp_names = set(grp_names)
+ return sorted(grp_names.difference(self.grp_names))
+
++ environmentid = property(fget=lambda self: self.evgid,
++ fset=lambda self, value: setattr(self, "evgid", value),
++ fdel=lambda self: setattr(self, "evgid", None),
++ doc="Compat. to treat comps groups/igroups the same")
++
+
+class InstalledGroups(object):
+ def __init__(self, db_path):
@@ -195412,7 +195438,7 @@ index 3793bad..e519bc1 100644
sack = repo.getPackageSack()
try:
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
-index e289a7a..c1f85e2 100644
+index e289a7a..ff0666c 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -48,6 +48,17 @@ def _open_no_umask(*args):
@@ -195507,7 +195533,32 @@ index e289a7a..c1f85e2 100644
% hdr):
return True
return False
-@@ -616,7 +626,7 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -592,7 +602,23 @@ class RPMDBPackageSack(PackageSackBase):
+ # will pick up any loads :)
+ pkgs = self.searchNames([pat])
+ if not pkgs:
+- break
++ # We need to do a big search for 'pkg*'
++ if misc.re_glob(pat):
++ break
++ # We need to do a big search for 'pkg-1.2'
++ if '-' in pat:
++ break
++ # We need to do a big search for 'pkg.noarch'
++ if '.' in pat:
++ break
++ # We don't need to do a big search for '0:pkg', because
++ # <en> isn't possible ... and envra matches the above.
++ # if ':' in pat:
++ # break
++
++ # At this point we have just found something that doesn't
++ # match, like "yum list zzuf" ... we don't want this to take
++ # the much slower path.
+ ret.extend(pkgs)
+ else:
+ return ret
+@@ -616,7 +642,7 @@ class RPMDBPackageSack(PackageSackBase):
for hdr, idx in self._get_packages():
if self._match_repattern(rpats, hdr, ignore_case):
self._makePackageObject(hdr, idx)
@@ -195516,7 +195567,7 @@ index e289a7a..c1f85e2 100644
pkgobjlist = self._idx2pkg.values()
# Remove gpg-pubkeys, as no sane callers expects/likes them...
-@@ -680,11 +690,56 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -680,11 +706,56 @@ class RPMDBPackageSack(PackageSackBase):
rpmdbv = self.simpleVersion(main_only=True)[0]
self._write_conflicts_new(pkgs, rpmdbv)
@@ -195573,7 +195624,7 @@ index e289a7a..c1f85e2 100644
misc.unlink_f(self._cachedir + '/file-requires')
misc.unlink_f(self._cachedir + '/pkgtups-checksums')
# We have a couple of options here, we can:
-@@ -701,15 +756,15 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -701,15 +772,15 @@ class RPMDBPackageSack(PackageSackBase):
if __debug__:
raise Errors.PackageSackError, 'Rpmdb checksum is invalid: %s' % caller
@@ -195592,7 +195643,7 @@ index e289a7a..c1f85e2 100644
if fo is None:
return None
frpmdbv = fo.readline()
-@@ -719,7 +774,7 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -719,7 +790,7 @@ class RPMDBPackageSack(PackageSackBase):
ret = []
try:
@@ -195601,7 +195652,7 @@ index e289a7a..c1f85e2 100644
pkgtups_num = int(_read_str(fo))
while pkgtups_num > 0:
pkgtups_num -= 1
-@@ -732,10 +787,13 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -732,10 +803,13 @@ class RPMDBPackageSack(PackageSackBase):
if fo.readline() != '': # Should be EOF
return None
except ValueError:
@@ -195617,7 +195668,7 @@ index e289a7a..c1f85e2 100644
return self._cached_conflicts_data
def transactionCacheConflictPackages(self, pkgs):
-@@ -752,6 +810,24 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -752,6 +826,24 @@ class RPMDBPackageSack(PackageSackBase):
return pkgs
@@ -195642,7 +195693,7 @@ index e289a7a..c1f85e2 100644
def transactionResultVersion(self, rpmdbv):
""" We are going to do a transaction, and the parameter will be the
rpmdb version when we finish. The idea being we can update all
-@@ -765,6 +841,10 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -765,6 +857,10 @@ class RPMDBPackageSack(PackageSackBase):
pkgs = self._trans_cache_store['conflicts']
self._write_conflicts_new(pkgs, rpmdbv)
@@ -195653,7 +195704,7 @@ index e289a7a..c1f85e2 100644
if 'file-requires' in self._trans_cache_store:
data = self._trans_cache_store['file-requires']
self._write_file_requires(rpmdbv, data)
-@@ -993,7 +1073,7 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -993,7 +1089,7 @@ class RPMDBPackageSack(PackageSackBase):
return
if not load_packages:
@@ -195662,7 +195713,7 @@ index e289a7a..c1f85e2 100644
for pkgtup in checksum_data:
if checksum_data[pkgtup] is None:
-@@ -1002,7 +1082,8 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -1002,7 +1098,8 @@ class RPMDBPackageSack(PackageSackBase):
(n, a, e, v, r) = pkgtup
pkg = self.searchNevra(n, e, v, r, a)
if not pkg:
@@ -195672,7 +195723,7 @@ index e289a7a..c1f85e2 100644
continue
pkg = pkg[0]
(T, D) = checksum_data[pkgtup]
-@@ -1088,7 +1169,7 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -1088,7 +1185,7 @@ class RPMDBPackageSack(PackageSackBase):
return
try:
@@ -195681,7 +195732,7 @@ index e289a7a..c1f85e2 100644
except (IOError, OSError), e:
return
-@@ -1456,7 +1537,7 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -1456,7 +1553,7 @@ class RPMDBPackageSack(PackageSackBase):
providers = set() # Speedup, as usual :)
problems = []
for pkg in sorted(pkgs): # The sort here is mainly for "UI"
@@ -195690,7 +195741,7 @@ index e289a7a..c1f85e2 100644
if rreq[0].startswith('rpmlib'): continue
if rreq in providers: continue
-@@ -1481,6 +1562,8 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -1481,6 +1578,8 @@ class RPMDBPackageSack(PackageSackBase):
prob = RPMDBProblemDependency(pkg, "conflicts", found=found,
conflicts=res)
problems.append(prob)
@@ -195699,7 +195750,7 @@ index e289a7a..c1f85e2 100644
return problems
def _iter_two_pkgs(self, ignore_provides):
-@@ -1562,11 +1645,11 @@ class RPMDBAdditionalData(object):
+@@ -1562,11 +1661,11 @@ class RPMDBAdditionalData(object):
self._packages = {} # pkgid = dir
if not os.path.exists(self.conf.db_path):
try:
@@ -195714,7 +195765,7 @@ index e289a7a..c1f85e2 100644
else:
if os.access(self.conf.db_path, os.W_OK):
self.conf.writable = True
-@@ -1622,6 +1705,7 @@ class RPMDBAdditionalDataPackage(object):
+@@ -1622,6 +1721,7 @@ class RPMDBAdditionalDataPackage(object):
'installed_by', 'changed_by',
'from_repo', 'from_repo_revision',
'from_repo_timestamp', 'releasever',
@@ -195722,7 +195773,7 @@ index e289a7a..c1f85e2 100644
'command_line'])
def __init__(self, conf, pkgdir, yumdb_cache=None):
-@@ -1708,7 +1792,7 @@ class RPMDBAdditionalDataPackage(object):
+@@ -1708,7 +1808,7 @@ class RPMDBAdditionalDataPackage(object):
def _write(self, attr, value):
# check for self._conf.writable before going on?
if not os.path.exists(self._mydir):
@@ -195731,7 +195782,7 @@ index e289a7a..c1f85e2 100644
attr = _sanitize(attr)
if attr in self._read_cached_data:
-@@ -1753,7 +1837,7 @@ class RPMDBAdditionalDataPackage(object):
+@@ -1753,7 +1853,7 @@ class RPMDBAdditionalDataPackage(object):
if attr.endswith('.tmp'):
raise AttributeError, "%s has no attribute %s" % (self, attr)
@@ -196165,10 +196216,10 @@ index 4d89d83..57a6764 100644
return msg
diff --git a/yum/update_md.py b/yum/update_md.py
-index 2cb1acb..3ac0010 100644
+index 2cb1acb..714de89 100644
--- a/yum/update_md.py
+++ b/yum/update_md.py
-@@ -79,11 +79,38 @@ class UpdateNotice(object):
+@@ -79,11 +79,53 @@ class UpdateNotice(object):
def __getitem__(self, item):
""" Allows scriptable metadata access (ie: un['update_id']). """
@@ -196198,8 +196249,23 @@ index 2cb1acb..3ac0010 100644
+ 'severity', 'release',
+ 'issued', 'updated', 'version', 'pushcount',
+ 'from', 'title', 'summary', 'description', 'solution'):
++ if data == 'status': # FIXME: See below...
++ continue
+ if self._md[data] != other._md[data]:
+ return False
++ # FIXME: Massive hack, Fedora is really broken and gives status=stable
++ # and status=testing for updateinfo notices, just depending on which
++ # repo. they come from.
++ data = 'status'
++ if self._md[data] != other._md[data]:
++ if self._md[data] not in ('stable', 'testing'):
++ return False
++ if other._md[data] not in ('stable', 'testing'):
++ return False
++ # They are both really "stable" ...
++ self._md[data] = 'stable'
++ other._md[data] = 'stable'
++
+ return True
+
+ def __ne__(self, other):
@@ -196208,7 +196274,7 @@ index 2cb1acb..3ac0010 100644
def text(self, skip_data=('files', 'summary', 'rights', 'solution')):
head = """
===============================================================================
-@@ -304,7 +331,9 @@ class UpdateNotice(object):
+@@ -304,7 +346,9 @@ class UpdateNotice(object):
to_xml(self._md['title']), to_xml(self._md['release']),
to_xml(self._md['issued'], attrib=True),
to_xml(self._md['description']))
@@ -196219,7 +196285,7 @@ index 2cb1acb..3ac0010 100644
if self._md['summary']:
msg += """ <summary>%s</summary>\n""" % (to_xml(self._md['summary']))
if self._md['solution']:
-@@ -345,7 +374,7 @@ class UpdateNotice(object):
+@@ -345,7 +389,7 @@ class UpdateNotice(object):
to_xml(pkg['version'], attrib=True),
to_xml(pkg['filename']))
msg += """ </collection>\n"""
@@ -196228,7 +196294,7 @@ index 2cb1acb..3ac0010 100644
msg += """</update>\n"""
return msg
-@@ -423,8 +452,41 @@ class UpdateMetadata(object):
+@@ -423,8 +467,41 @@ class UpdateMetadata(object):
def add_notice(self, un):
""" Add an UpdateNotice object. This should be fully populated with
data, esp. update_id and pkglist/packages. """
@@ -196272,7 +196338,7 @@ index 2cb1acb..3ac0010 100644
self._notices[un['update_id']] = un
for pkg in un['pkglist']:
-@@ -435,6 +497,8 @@ class UpdateMetadata(object):
+@@ -435,16 +512,20 @@ class UpdateMetadata(object):
no = self._no_cache.setdefault(filedata['name'], set())
no.add(un)
@@ -196281,19 +196347,35 @@ index 2cb1acb..3ac0010 100644
def add(self, obj, mdtype='updateinfo'):
""" Parse a metadata from a given YumRepository, file, or filename. """
if not obj:
-@@ -464,7 +528,8 @@ class UpdateMetadata(object):
+ raise UpdateNoticeException
++ repoid = None
+ if type(obj) in (type(''), type(u'')):
+ unfile = decompress(obj)
+ infile = open(unfile, 'rt')
+
+ elif isinstance(obj, YumRepository):
+ if obj.id not in self._repos:
++ repoid = obj.id
+ self._repos.append(obj.id)
+ md = obj.retrieveMD(mdtype)
+ if not md:
+@@ -464,7 +545,12 @@ class UpdateMetadata(object):
print >> sys.stderr, "An update notice is broken, skipping."
# what else should we do?
continue
- self.add_notice(un)
+ if not self.add_notice(un):
-+ print >> sys.stderr, "An update notice is broken, or duplicate, skipping:", un['update_id']
++ if repoid is None:
++ upid = un['update_id']
++ else:
++ upid = "%s/%s" % (repoid, un['update_id'])
++ print >> sys.stderr, "An update notice is broken, or duplicate, skipping:", upid
def __unicode__(self):
ret = u''
diff --git a/yum/updateinfo.py b/yum/updateinfo.py
new file mode 100644
-index 0000000..7d37a76
+index 0000000..8c6e295
--- /dev/null
+++ b/yum/updateinfo.py
@@ -0,0 +1,515 @@
@@ -196586,7 +196668,6 @@ index 0000000..7d37a76
+ '''
+ Remove packages from the transaction, using the updateinfo data.
+ '''
-+ md_info = base.upinfo
+
+ def ysp_del_pkg(tspkg):
+ """ Deletes a package within a transaction. """
@@ -196602,6 +196683,7 @@ index 0000000..7d37a76
+ if _no_options(opts):
+ return 0, 0, 0
+
++ md_info = base.upinfo
+ tot = 0
+ cnt = 0
+ used_map = _ysp_gen_used_map(opts)
@@ -196671,8 +196753,6 @@ index 0000000..7d37a76
+ Exclude all packages to do with updates, using the updateinfo data.
+ '''
+
-+ md_info = base.upinfo
-+
+ def ysp_del_pkg(pkg, reason="updateinfo"):
+ """ Deletes a package from all trees that yum knows about """
+ base.verbose_logger.log(INFO_1,
@@ -196687,6 +196767,8 @@ index 0000000..7d37a76
+ if _no_options(opts):
+ return 0, 0
+
++ md_info = base.upinfo
++
+ used_map = _ysp_gen_used_map(opts)
+
+ # In theory the official API is:
@@ -196728,8 +196810,6 @@ index 0000000..7d37a76
+ Exclude all packages, using the updateinfo data.
+ '''
+
-+ md_info = base.upinfo
-+
+ def ysp_del_pkg(pkg, reason="updateinfo"):
+ """ Deletes a package from all trees that yum knows about """
+ base.verbose_logger.log(INFO_1,
@@ -196744,6 +196824,8 @@ index 0000000..7d37a76
+ if _no_options(opts):
+ return 0, 0
+
++ md_info = base.upinfo
++
+ used_map = _ysp_gen_used_map(opts)
+
+ pkgs = base.pkgSack.returnPackages()
diff --git a/yum.spec b/yum.spec
index 7c838bb..9a0a1da 100644
--- a/yum.spec
+++ b/yum.spec
@@ -41,7 +41,7 @@ BuildRequires: bash-completion
Summary: RPM package installer/updater/manager
Name: yum
Version: 3.4.3
-Release: 89%{?dist}
+Release: 90%{?dist}
License: GPLv2+
Group: System Environment/Base
Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz
@@ -52,7 +52,6 @@ Patch4: no-more-exactarchlist.patch
Patch5: geode-arch.patch
Patch6: yum-HEAD.patch
Patch7: yum-ppc64-preferred.patch
-Patch10: yum-3.4.3-comps.patch
Patch20: yum-manpage-files.patch
Patch21: yum-completion-helper.patch
@@ -177,7 +176,6 @@ Install this package if you want auto yum updates nightly via cron.
%patch5 -p1
%patch6 -p1
%patch7 -p1
-%patch10 -p1
%patch20 -p1
%patch21 -p1
%patch1 -p1
@@ -404,6 +402,13 @@ exit 0
%endif
%changelog
+* Wed May 8 2013 James Antill <james at fedoraproject.org> - 3.4.3-90
+- Massive hack for Fedora/updateinfo stable vs. testing statuses. BZ 960642.
+- Don't load updateinfo when we don't have to.
+- Tell which repo. we are skipping the updateinfo notice from.
+- Compat. code so we can treat groups/igroups the same. BZ 955236.
+- Don't highlight the empty space, Eg. --showdups list.
+
* Thu May 2 2013 Bill Nottingham <notting at redhat.com> - 3.4.3-89
- Fix defaults-for-environment optional groups change. BZ 958531
More information about the scm-commits
mailing list