[yum] update to latest HEAD.

James Antill james at fedoraproject.org
Thu Apr 18 21:16:32 UTC 2013


commit d952ed53d552edb0edd80a5bea9c9b0269e82db7
Author: James Antill <james at and.org>
Date:   Thu Apr 18 17:16:26 2013 -0400

    update to latest HEAD.
    
    - Move yum-security into core.
    - A bunch of minor fixes for yum-cron.
    - Update yum-cron to add security/minimal/etc. updates.
    - Add socks support to proxy config.

 yum-HEAD.patch | 1729 +++++++++++++++++++++++++++++++++++++++++++++-----------
 yum.spec       |   13 +-
 2 files changed, 1404 insertions(+), 338 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index b138508..4ee5a92 100644
--- a/yum-HEAD.patch
+++ b/yum-HEAD.patch
@@ -99,7 +99,7 @@ index 2f6154e..2e5a052 100644
 diff --git a/cli.py b/cli.py
 old mode 100644
 new mode 100755
-index 6056d38..8ea5d1f
+index 6056d38..ba2e343
 --- a/cli.py
 +++ b/cli.py
 @@ -25,7 +25,7 @@ import sys
@@ -154,12 +154,14 @@ index 6056d38..8ea5d1f
         
      def __init__(self):
          # handle sigquit early on
-@@ -104,17 +107,28 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -104,17 +107,30 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          self.registerCommand(yumcommands.CheckRpmdbCommand())
          self.registerCommand(yumcommands.DistroSyncCommand())
          self.registerCommand(yumcommands.LoadTransactionCommand())
 +        self.registerCommand(yumcommands.SwapCommand())
 +        self.registerCommand(yumcommands.RepoPkgsCommand())
++        self.registerCommand(yumcommands.UpdateinfoCommand())
++        self.registerCommand(yumcommands.UpdateMinimalCommand())
  
      def registerCommand(self, command):
 +        """Register a :class:`yumcommands.YumCommand` so that it can be called by
@@ -186,7 +188,7 @@ index 6056d38..8ea5d1f
          if self._repos and thisrepo is None:
              return self._repos
              
-@@ -163,8 +177,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -163,8 +179,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          mainopts = yum.misc.GenericHolder()
          mainopts.items = []
  
@@ -206,7 +208,7 @@ index 6056d38..8ea5d1f
              period = k.find('.') 
              if period != -1:
                  repo = k[:period]
-@@ -180,13 +204,15 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -180,13 +206,15 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          
          self.main_setopts = mainopts
          self.repo_setopts = repoopts
@@ -227,7 +229,7 @@ index 6056d38..8ea5d1f
          self.optparser = YumOptionParser(base=self, usage=self._makeUsage())
          
          # Parse only command line options that affect basic yum setup
-@@ -199,7 +225,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -199,7 +227,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              opts.verbose = False
  
          # go through all the setopts and set the global ones
@@ -236,7 +238,7 @@ index 6056d38..8ea5d1f
          
          if self.main_setopts:
              for opt in self.main_setopts.items:
-@@ -229,6 +255,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -229,6 +257,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              pc.releasever = opts.releasever
              self.conf
              
@@ -249,7 +251,7 @@ index 6056d38..8ea5d1f
              # now set  all the non-first-start opts from main from our setopts
              if self.main_setopts:
                  for opt in self.main_setopts.items:
-@@ -238,10 +270,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -238,10 +272,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                      setattr(self.conf, opt, getattr(self.main_setopts, opt))
  
          except yum.Errors.ConfigError, e:
@@ -266,7 +268,7 @@ index 6056d38..8ea5d1f
              sys.exit(1)
  
          # update usage in case plugins have added commands
-@@ -290,9 +326,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -290,9 +328,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                                     self.term.MODE['normal'])
                  print _("  Installed: %s-%s at %s") %(name, ver,
                                                     sm_ui_time(pkg.installtime))
@@ -278,7 +280,7 @@ index 6056d38..8ea5d1f
                                                      sm_ui_date(pkg.committime))
              sys.exit(0)
  
-@@ -318,10 +354,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -318,10 +356,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          time.sleep(sleeptime)
          
      def parseCommands(self):
@@ -295,7 +297,7 @@ index 6056d38..8ea5d1f
          self.verbose_logger.log(yum.logginglevels.DEBUG_4,
                                  'COMMAND: %s', self.cmdstring)
          self.verbose_logger.log(yum.logginglevels.DEBUG_4,
-@@ -365,7 +403,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -365,7 +405,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          self.history.write_addon_data('shell-cmds', data)
  
      def doShell(self):
@@ -308,7 +310,7 @@ index 6056d38..8ea5d1f
  
          yumshell = shell.YumShell(base=self)
  
-@@ -382,8 +424,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -382,8 +426,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return yumshell.result, yumshell.resultmsgs
  
      def errorSummary(self, errstring):
@@ -323,7 +325,7 @@ index 6056d38..8ea5d1f
          summary = ''
          # do disk space report first
          p = re.compile('needs (\d+)MB on the (\S+) filesystem')
-@@ -407,17 +453,45 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -407,17 +455,45 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return summary
  
  
@@ -379,7 +381,7 @@ index 6056d38..8ea5d1f
          # at this point we know the args are valid - we don't know their meaning
          # but we know we're not being sent garbage
          
-@@ -435,14 +509,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -435,14 +511,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              try:
                  self._getTs(needTsRemove)
              except yum.Errors.YumBaseError, e:
@@ -408,7 +410,7 @@ index 6056d38..8ea5d1f
          # just make sure there's not, well, nothing to do
          if len(self.tsInfo) == 0:
              self.verbose_logger.info(_('Trying to run the transaction but nothing to do. Exiting.'))
-@@ -453,7 +537,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -453,7 +539,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          lsts = self.listTransaction()
          if self.verbose_logger.isEnabledFor(yum.logginglevels.INFO_1):
              self.verbose_logger.log(yum.logginglevels.INFO_1, lsts)
@@ -417,7 +419,7 @@ index 6056d38..8ea5d1f
              #  If we are in quiet, and assumeyes isn't on we want to output
              # at least the transaction list anyway.
              self.logger.warn(lsts)
-@@ -463,7 +547,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -463,7 +549,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          rmpkgs = []
          stuff_to_download = False
          install_only = True
@@ -425,7 +427,7 @@ index 6056d38..8ea5d1f
          for txmbr in self.tsInfo.getMembers():
              if txmbr.ts_state not in ('i', 'u'):
                  install_only = False
-@@ -471,7 +554,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -471,7 +556,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  if po:
                      rmpkgs.append(po)
              else:
@@ -433,7 +435,7 @@ index 6056d38..8ea5d1f
                  stuff_to_download = True
                  po = txmbr.po
                  if po:
-@@ -489,19 +571,30 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -489,19 +573,30 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          else:
              self.reportDownloadSize(downloadpkgs, install_only)
          
@@ -468,7 +470,7 @@ index 6056d38..8ea5d1f
              for key in problems:
                  errors = yum.misc.unique(problems[key])
                  for error in errors:
-@@ -520,8 +613,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -520,8 +615,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
          rcd_st = time.time()
          self.verbose_logger.log(yum.logginglevels.INFO_2, 
@@ -479,7 +481,7 @@ index 6056d38..8ea5d1f
          if msgs:
              rpmlib_only = True
              for msg in msgs:
-@@ -532,19 +626,23 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -532,19 +628,23 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  print _("ERROR You need to update rpm to handle:")
              else:
                  print _('ERROR with transaction check vs depsolve:')
@@ -506,7 +508,7 @@ index 6056d38..8ea5d1f
          if not self.conf.diskspacecheck:
              self.tsInfo.probFilterFlags.append(rpm.RPMPROB_FILTER_DISKSPACE)
              
-@@ -556,16 +654,16 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -556,16 +656,16 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          del testcb
  
          if len(tserrors) > 0:
@@ -526,7 +528,7 @@ index 6056d38..8ea5d1f
          
          # unset the sigquit handler
          signal.signal(signal.SIGQUIT, signal.SIG_DFL)
-@@ -595,7 +693,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -595,7 +695,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          if self.conf.debuglevel < 2:
              cb.display.output = False
  
@@ -535,7 +537,7 @@ index 6056d38..8ea5d1f
          resultobject = self.runTransaction(cb=cb)
  
          self.verbose_logger.debug('Transaction time: %0.3f' % (time.time() - ts_st))
-@@ -609,12 +707,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -609,12 +709,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return resultobject.return_code
          
      def gpgsigcheck(self, pkgs):
@@ -555,7 +557,7 @@ index 6056d38..8ea5d1f
          for po in pkgs:
              result, errmsg = self.sigCheckPkg(po)
  
-@@ -623,7 +723,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -623,7 +725,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  continue            
  
              elif result == 1:
@@ -565,7 +567,7 @@ index 6056d38..8ea5d1f
                      raise yum.Errors.YumBaseError, \
                              _('Refusing to automatically import keys when running ' \
                              'unattended.\nUse "-y" to override.')
-@@ -691,12 +792,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -691,12 +794,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                                       ", ".join(matches))
              self.verbose_logger.log(yum.logginglevels.INFO_2, msg)
  
@@ -634,7 +636,7 @@ index 6056d38..8ea5d1f
          # get the list of available packages
          # iterate over the user's list
          # add packages to Transaction holding class if they match.
-@@ -710,11 +861,36 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -710,11 +863,36 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          for arg in userlist:
              if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
                                            os.path.exists(arg))):
@@ -673,7 +675,7 @@ index 6056d38..8ea5d1f
              except yum.Errors.InstallError:
                  self.verbose_logger.log(yum.logginglevels.INFO_2,
                                          _('No package %s%s%s available.'),
-@@ -723,6 +899,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -723,6 +901,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  self._maybeYouMeant(arg)
              else:
                  done = True
@@ -681,7 +683,7 @@ index 6056d38..8ea5d1f
          if len(self.tsInfo) > oldcount:
              change = len(self.tsInfo) - oldcount
              return 2, [P_('%d package to install', '%d packages to install', change) % change]
-@@ -732,9 +909,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -732,9 +911,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, [_('Nothing to do')]
          
      def updatePkgs(self, userlist, quiet=0, update_to=False):
@@ -712,7 +714,7 @@ index 6056d38..8ea5d1f
          # if there is no userlist, then do global update below
          # this is probably 90% of the calls
          # if there is a userlist then it's for updating pkgs, not obsoleting
-@@ -745,34 +940,46 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -745,34 +942,46 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
          else:
              # go through the userlist - look for items that are local rpms. If we find them
@@ -776,7 +778,7 @@ index 6056d38..8ea5d1f
  
          level = 'diff'
          if userlist and userlist[0] in ('full', 'diff', 'different'):
-@@ -831,6 +1038,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -831,6 +1040,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                          continue
  
                      nayi = napkg.yumdb_info
@@ -784,7 +786,7 @@ index 6056d38..8ea5d1f
                      for apkg in self.pkgSack.searchPkgTuple(napkg.pkgtup):
                          if ('checksum_type' in nayi and
                              'checksum_data' in nayi and
-@@ -861,19 +1069,58 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -861,19 +1071,58 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  dupdates.extend(self.downgrade(name=n, epoch=e, ver=v, rel=r))
  
          if dupdates:
@@ -851,7 +853,7 @@ index 6056d38..8ea5d1f
              if not rms:
                  self._checkMaybeYouMeant(arg, always_output=False, rpmdb_only=True)
              all_rms.extend(rms)
-@@ -884,12 +1131,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -884,12 +1133,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return 0, [_('No Packages marked for removal')]
      
      def downgradePkgs(self, userlist):
@@ -879,7 +881,7 @@ index 6056d38..8ea5d1f
          for arg in userlist:
              if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
                                            os.path.exists(arg))):
-@@ -905,26 +1164,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -905,26 +1166,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                                          self.term.MODE['bold'], arg,
                                          self.term.MODE['normal'])
                  self._maybeYouMeant(arg)
@@ -928,7 +930,7 @@ index 6056d38..8ea5d1f
              except yum.Errors.ReinstallRemoveError:
                  self._checkMaybeYouMeant(arg, always_output=False)
              except yum.Errors.ReinstallInstallError, e:
-@@ -940,22 +1217,38 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -940,22 +1219,38 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              except yum.Errors.ReinstallError, e:
                  assert False, "Shouldn't happen, but just in case"
                  self.verbose_logger.log(yum.logginglevels.INFO_2, e)
@@ -971,7 +973,7 @@ index 6056d38..8ea5d1f
  
          installing = False
          for pkg in filelist:
-@@ -971,23 +1264,29 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -971,23 +1266,29 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return 2, [_('Package(s) to install')]
          return 0, [_('Nothing to do')]
  
@@ -1017,7 +1019,7 @@ index 6056d38..8ea5d1f
          
          pkgnarrow = 'all'
          done_hidden_available = False
-@@ -1003,7 +1302,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1003,7 +1304,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  pkgnarrow = extcmds.pop(0)
              
          ypl = self.doPackageLists(pkgnarrow=pkgnarrow, patterns=extcmds,
@@ -1026,7 +1028,7 @@ index 6056d38..8ea5d1f
          if self.conf.showdupesfromrepos:
              ypl.available += ypl.reinstall_available
  
-@@ -1017,8 +1316,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1017,8 +1318,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return ypl
  
      def search(self, args):
@@ -1054,7 +1056,7 @@ index 6056d38..8ea5d1f
          
          # call the yum module search function with lists of tags to search
          # and what to search for
-@@ -1053,7 +1369,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1053,7 +1371,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                          print ""
                      else:
                          mkeys = set(keys)
@@ -1063,7 +1065,7 @@ index 6056d38..8ea5d1f
                      okeys = keys
                  pos.add(po)
                  akeys.update(keys)
-@@ -1104,13 +1420,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1104,13 +1422,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  self.logger.warning(_('Warning: No matches found for: %s'), arg)
  
          if not akeys:
@@ -1091,7 +1093,7 @@ index 6056d38..8ea5d1f
          pkgs = []
          for arg in args:
              if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
-@@ -1118,10 +1445,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1118,10 +1447,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  thispkg = yum.packages.YumUrlPackage(self, self.ts, arg)
                  pkgs.append(thispkg)
              elif self.conf.showdupesfromrepos:
@@ -1106,7 +1108,7 @@ index 6056d38..8ea5d1f
                  except yum.Errors.PackageSackError:
                      pass
                  
-@@ -1131,10 +1460,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1131,10 +1462,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, []
  
      def provides(self, args):
@@ -1130,7 +1132,7 @@ index 6056d38..8ea5d1f
          old_sdup = self.conf.showdupesfromrepos
          # For output, as searchPackageProvides() is always in showdups mode
          self.conf.showdupesfromrepos = True
-@@ -1147,6 +1485,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1147,6 +1487,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              paths = set(sys.path + os.environ['PATH'].split(':'))
              nargs = []
              for arg in args:
@@ -1139,7 +1141,7 @@ index 6056d38..8ea5d1f
                  if yum.misc.re_filename(arg) or yum.misc.re_glob(arg):
                      continue
                  for path in paths:
-@@ -1158,25 +1498,82 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1158,25 +1500,82 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          self.conf.showdupesfromrepos = old_sdup
  
          if len(matching) == 0:
@@ -1228,7 +1230,7 @@ index 6056d38..8ea5d1f
          hdrcode = pkgcode = xmlcode = dbcode = expccode = 0
          pkgresults = hdrresults = xmlresults = dbresults = expcresults = []
          msg = self.fmtKeyValFill(_('Cleaning repos: '), 
-@@ -1184,7 +1581,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1184,7 +1583,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          self.verbose_logger.log(yum.logginglevels.INFO_2, msg)
          if 'all' in userlist:
              self.verbose_logger.log(yum.logginglevels.INFO_2,
@@ -1237,7 +1239,7 @@ index 6056d38..8ea5d1f
              pkgcode, pkgresults = self.cleanPackages()
              hdrcode, hdrresults = self.cleanHeaders()
              xmlcode, xmlresults = self.cleanMetadata()
-@@ -1200,10 +1597,10 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1200,10 +1599,10 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return code, []
              
          if 'headers' in userlist:
@@ -1250,7 +1252,7 @@ index 6056d38..8ea5d1f
              pkgcode, pkgresults = self.cleanPackages()
          if 'metadata' in userlist:
              self.logger.debug(_('Cleaning up xml metadata'))
-@@ -1228,138 +1625,265 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1228,138 +1627,265 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return code, []
  
      def returnGroupLists(self, userlist):
@@ -1598,17 +1600,17 @@ index 6056d38..8ea5d1f
                  continue
              
          if not pkgs_used:
-@@ -1368,17 +1892,61 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1368,17 +1894,61 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return 2, [P_('%d package to Install', '%d packages to Install', len(pkgs_used)) % len(pkgs_used)]
  
      def removeGroups(self, grouplist):
 -        """Remove only packages of the named group(s). Do not recurse."""
 +        """Mark the packages in the given groups for removal.
- 
++
 +        :param grouplist: a list of names or wildcards specifying
 +           groups to be removed
 +        :return: (exit_code, [ errors ])
-+
+ 
 +        exit_code is::
 +
 +            0 = we're done, exit
@@ -1668,7 +1670,7 @@ index 6056d38..8ea5d1f
                  
          if not pkgs_used:
              return 0, [_('No packages to remove from groups')]
-@@ -1389,7 +1957,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1389,7 +1959,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
      def _promptWanted(self):
          # shortcut for the always-off/always-on options
@@ -1677,7 +1679,7 @@ index 6056d38..8ea5d1f
              return False
          if self.conf.alwaysprompt:
              return True
-@@ -1397,10 +1965,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1397,10 +1967,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          # prompt if:
          #  package was added to fill a dependency
          #  package is being removed
@@ -1689,7 +1691,7 @@ index 6056d38..8ea5d1f
                     txmbr.name not in self.extcmds:
                  return True
          
-@@ -1408,11 +1975,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1408,11 +1977,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return False
  
      def usage(self):
@@ -1703,7 +1705,7 @@ index 6056d38..8ea5d1f
          sys.stdout.write(self.optparser.get_usage())
      
      def _installable(self, pkg, ematch=False):
-@@ -1468,9 +2035,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1468,9 +2037,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return False
  
  class YumOptionParser(OptionParser):
@@ -1715,7 +1717,7 @@ index 6056d38..8ea5d1f
  
      def __init__(self,base, **kwargs):
          # check if this is called with a utils=True/False parameter
-@@ -1488,13 +2055,23 @@ class YumOptionParser(OptionParser):
+@@ -1488,13 +2057,23 @@ class YumOptionParser(OptionParser):
          self._addYumBasicOptions()
  
      def error(self, msg):
@@ -1741,7 +1743,7 @@ index 6056d38..8ea5d1f
          try:
              args = _filtercmdline(
                          ('--noplugins','--version','-q', '-v', "--quiet", "--verbose"), 
-@@ -1521,7 +2098,15 @@ class YumOptionParser(OptionParser):
+@@ -1521,7 +2100,15 @@ class YumOptionParser(OptionParser):
          return ret
          
      def setupYumConfig(self, args=None):
@@ -1758,7 +1760,7 @@ index 6056d38..8ea5d1f
          if not args:
              (opts, cmds) = self.parse_args()
          else:
-@@ -1533,16 +2118,22 @@ class YumOptionParser(OptionParser):
+@@ -1533,16 +2120,30 @@ class YumOptionParser(OptionParser):
          try:
              # config file is parsed and moving us forward
              # set some things in it.
@@ -1779,6 +1781,14 @@ index 6056d38..8ea5d1f
 +            self.base.conf.downloadonly = opts.dlonly
 +            self.base.conf.downloaddir = opts.dldir
 +
++            # Store all the updateinfo filters somewhere...
++            self.base.updateinfo_filters['security'] = opts.security
++            self.base.updateinfo_filters['bugfix'] = opts.bugfix
++            self.base.updateinfo_filters['advs'] = self._splitArg(opts.advs)
++            self.base.updateinfo_filters['bzs']  = self._splitArg(opts.bzs)
++            self.base.updateinfo_filters['cves'] = self._splitArg(opts.cves)
++            self.base.updateinfo_filters['sevs'] = self._splitArg(opts.sevs)
++
 +            #  Treat users like root as much as possible:
 +            if not self.base.setCacheDir():
                  self.base.conf.cache = 1
@@ -1787,7 +1797,7 @@ index 6056d38..8ea5d1f
                  self.base.conf.cache = 1
  
              if opts.obsoletes:
-@@ -1610,10 +2201,6 @@ class YumOptionParser(OptionParser):
+@@ -1610,10 +2211,6 @@ class YumOptionParser(OptionParser):
                      self.base.usage()
                      sys.exit(1)
  
@@ -1798,7 +1808,7 @@ index 6056d38..8ea5d1f
              # Disable all gpg key checking, if requested.
              if opts.nogpgcheck:
                  #  Altering the normal configs. doesn't work too well, esp. with
-@@ -1623,7 +2210,7 @@ class YumOptionParser(OptionParser):
+@@ -1623,7 +2220,7 @@ class YumOptionParser(OptionParser):
                      repo._override_sigchecks = True
                              
          except ValueError, e:
@@ -1807,7 +1817,7 @@ index 6056d38..8ea5d1f
              self.base.usage()
              sys.exit(1)
           
-@@ -1640,10 +2227,18 @@ class YumOptionParser(OptionParser):
+@@ -1640,10 +2237,18 @@ class YumOptionParser(OptionParser):
          sys.exit(1)
  
      def getRoot(self,opts):
@@ -1827,7 +1837,7 @@ index 6056d38..8ea5d1f
              if os.access(opts.installroot+'/'+opts.conffile, os.R_OK):
                  opts.conffile = opts.installroot+'/'+opts.conffile
              elif opts.conffile == '/etc/yum/yum.conf':
-@@ -1701,6 +2296,9 @@ class YumOptionParser(OptionParser):
+@@ -1701,6 +2306,9 @@ class YumOptionParser(OptionParser):
          group.add_option("--showduplicates", dest="showdupesfromrepos",
                          action="store_true",
                  help=_("show duplicates, in repos, in list/search commands"))
@@ -1837,7 +1847,7 @@ index 6056d38..8ea5d1f
          group.add_option("-e", "--errorlevel", dest="errorlevel", default=None,
                  help=_("error output level"), type='int',
                  metavar='[error level]')
-@@ -1713,6 +2311,10 @@ class YumOptionParser(OptionParser):
+@@ -1713,6 +2321,10 @@ class YumOptionParser(OptionParser):
                          help=_("verbose operation"))
          group.add_option("-y", "--assumeyes", dest="assumeyes",
                  action="store_true", help=_("answer yes for all questions"))
@@ -1848,7 +1858,7 @@ index 6056d38..8ea5d1f
          group.add_option("--version", action="store_true", 
                  help=_("show Yum version and exit"))
          group.add_option("--installroot", help=_("set install root"), 
-@@ -1748,6 +2350,10 @@ class YumOptionParser(OptionParser):
+@@ -1748,9 +2360,29 @@ class YumOptionParser(OptionParser):
                  help=_("control whether color is used"))
          group.add_option("", "--releasever", dest="releasever", default=None, 
                  help=_("set value of $releasever in yum config and repo files"))
@@ -1859,6 +1869,25 @@ index 6056d38..8ea5d1f
          group.add_option("", "--setopt", dest="setopts", default=[],
                  action="append", help=_("set arbitrary config and repo options"))
  
++        # Updateinfo options...
++        group.add_option("--bugfix", action="store_true", 
++                help=_("Include bugfix relevant packages, in updates"))
++        group.add_option("--security", action="store_true", 
++                help=_("Include security relevant packages, in updates"))
++
++        group.add_option("--advisory", "--advisories", dest="advs", default=[],
++                action="append", help=_("Include packages needed to fix the given advisory, in updates"))
++        group.add_option("--bzs", default=[],
++                action="append", help=_("Include packages needed to fix the given BZ, in updates"))
++        group.add_option("--cves", default=[],
++                action="append", help=_("Include packages needed to fix the given CVE, in updates"))
++        group.add_option("--sec-severity", "--secseverity", default=[],
++                         dest="sevs", action="append",
++                help=_("Include security relevant packages matching the severity, in updates"))
++
+         
+ def _filtercmdline(novalopts, valopts, args):
+     '''Keep only specific options from the command line argument list
 diff --git a/completion-helper.py b/completion-helper.py
 new file mode 100755
 index 0000000..1102fd6
@@ -3735,11 +3764,20 @@ index 63c5ec0..0000000
 -exit $RETVAL
 diff --git a/etc/yum-cron-hourly.conf b/etc/yum-cron-hourly.conf
 new file mode 100644
-index 0000000..ece67c4
+index 0000000..b17448c
 --- /dev/null
 +++ b/etc/yum-cron-hourly.conf
-@@ -0,0 +1,59 @@
+@@ -0,0 +1,68 @@
 +[commands]
++#  What kind of update to use:
++# default                            = yum upgrade
++# security                           = yum --security upgrade
++# security-severity:Critical         = yum --sec-severity=Critical upgrade
++# minimal                            = yum --bugfix upgrade-minimal
++# minimal-security                   = yum --security upgrade-minimal
++# minimal-security-severity:Critical =  --sec-severity=Critical upgrade-minimal
++update_cmd = default
++
 +# Whether a message should emitted when updates are available.
 +update_messages = no
 +
@@ -3800,11 +3838,20 @@ index 0000000..ece67c4
 +# skip_broken = True
 diff --git a/etc/yum-cron.conf b/etc/yum-cron.conf
 new file mode 100644
-index 0000000..d19fce3
+index 0000000..3221802
 --- /dev/null
 +++ b/etc/yum-cron.conf
-@@ -0,0 +1,59 @@
+@@ -0,0 +1,68 @@
 +[commands]
++#  What kind of update to use:
++# default                            = yum upgrade
++# security                           = yum --security upgrade
++# security-severity:Critical         = yum --sec-severity=Critical upgrade
++# minimal                            = yum --bugfix upgrade-minimal
++# minimal-security                   = yum --security upgrade-minimal
++# minimal-security-severity:Critical =  --sec-severity=Critical upgrade-minimal
++update_cmd = default
++
 +# Whether a message should emitted when updates are available.
 +update_messages = yes
 +
@@ -183587,10 +183634,10 @@ index 0000000..28e1964
 +- Check if we're running as root; exit nicely.
 diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
 new file mode 100755
-index 0000000..089cad4
+index 0000000..0b6af7d
 --- /dev/null
 +++ b/yum-cron/yum-cron.py
-@@ -0,0 +1,1118 @@
+@@ -0,0 +1,1119 @@
 +#!/usr/bin/python -tt
 +import os
 +import sys
@@ -183603,7 +183650,6 @@ index 0000000..089cad4
 +from yum.parser import ConfigPreProcessor
 +from ConfigParser import ConfigParser, ParsingError
 +from yum.constants import *
-+from yum.update_md import UpdateMetadata
 +from email.mime.text import MIMEText
 +from yum.i18n import to_str, to_utf8, to_unicode, utf8_width, utf8_width_fill, utf8_text_fill
 +from yum import  _, P_
@@ -184295,6 +184341,7 @@ index 0000000..089cad4
 +    email_host = Option("localhost")
 +    email_port = IntOption(25)
 +    update_messages = BoolOption(False)
++    update_cmd = Option("default")
 +    apply_updates = BoolOption(False)
 +    download_updates = BoolOption(False)
 +    yum_config_file = Option("/etc/yum.conf")
@@ -184389,6 +184436,9 @@ index 0000000..089cad4
 +            if os.geteuid() != 0:
 +                self.setCacheDir()
 +
++            # Turn off the plugins line
++            self.preconf.debuglevel = 0
++
 +            # Create the configuration
 +            self.conf
 +
@@ -184413,22 +184463,7 @@ index 0000000..089cad4
 +
 +    def populateUpdateMetadata(self):
 +        """Populate the metadata for the packages in the update."""
-+
-+        self.updateMetadata = UpdateMetadata()
-+        repos = []
-+
-+        for (new, old) in self.up.getUpdatesTuples():
-+            pkg = self.getPackageObject(new)
-+            if pkg.repoid not in repos:
-+                repo = self.repos.getRepo(pkg.repoid)
-+                repos.append(repo.id)
-+                try: # grab the updateinfo.xml.gz from the repodata
-+                    md = repo.retrieveMD('updateinfo')
-+                except Exception: # can't find any; silently move on
-+                    continue
-+                md = gzip.open(md)
-+                self.updateMetadata.add(md)
-+                md.close()
++        self.upinfo
 +
 +    def refreshUpdates(self):
 +        """Check whether updates are available.
@@ -184437,27 +184472,37 @@ index 0000000..089cad4
 +           available
 +        """
 +        try:
-+            updatesTuples = self.up.getUpdatesTuples()
-+            # If there are no updates, return False
-+            if not updatesTuples:
-+                return False
++            #  Just call .update() because it does obsoletes loops, and group
++            # objects. etc.
 +
-+            # figure out the updates
-+            for (new, old) in updatesTuples:
-+                updates_available = True
-+                updating = self.getPackageObject(new)
-+                updated = self.rpmdb.searchPkgTuple(old)[0]
-+            
-+                self.tsInfo.addUpdate(updating, updated)
++            update_cmd = self.opts.update_cmd
++            idx = update_cmd.find("security-severity:")
++            if idx != -1:
++                sevs       = update_cmd[idx + len("security-severity:"):]
++                update_cmd = update_cmd[:idx + len("security")]
++                self.updateinfo_filters['sevs'] = sevs.split(",")
 +
-+            # and the obsoletes
-+            if self.conf.obsoletes:
-+                for (obs, inst) in self.up.getObsoletesTuples():
-+                    obsoleting = self.getPackageObject(obs)
-+                    installed = self.rpmdb.searchPkgTuple(inst)[0]
-+                
-+                    self.tsInfo.addObsoleting(obsoleting, installed)
-+                    self.tsInfo.addObsoleted(installed, obsoleting)
++
++            if self.opts.update_cmd in ('minimal', 'minimal-security'):
++                if not updateinfo.update_minimal(self):
++                    return False
++                self.updateinfo_filters['bugfix'] = True
++            elif self.opts.update_cmd in ('default', 'security',
++                                          'default-security'):
++                if not self.update():
++                    return False
++            else:
++                # return False ?
++                self.opts.update_cmd = 'default'
++                if not self.update():
++                    return False
++
++            if self.opts.update_cmd.endswith("security"):
++                self.updateinfo_filters['security'] = True
++                updateinfo.remove_txmbrs(self)
++            elif self.opts.update_cmd == 'minimal':
++                self.updateinfo_filters['bugfix'] = True
++                updateinfo.remove_txmbrs(self)
 +
 +        except Exception, e:
 +            self.emitCheckFailed("%s" %(e,))
@@ -184473,6 +184518,9 @@ index 0000000..089cad4
 +        :return: Boolean indicating whether there are any updates to
 +           the group available
 +        """
++        if self.conf.group_command == 'objects':
++            return False
++
 +        update_available = False
 +        try:
 +            for group_string in self.opts.group_list:
@@ -184859,7 +184907,7 @@ index 0000000..06dee5f
 +exec /usr/sbin/yum-cron
 diff --git a/yum-cron/yum-hourly.cron.sh b/yum-cron/yum-hourly.cron.sh
 new file mode 100755
-index 0000000..557dd4d
+index 0000000..f0b77a9
 --- /dev/null
 +++ b/yum-cron/yum-hourly.cron.sh
 @@ -0,0 +1,11 @@
@@ -184873,7 +184921,7 @@ index 0000000..557dd4d
 +fi
 +
 +# Action!
-+exec /usr/sbin/yum-cron -C /etc/yum/yum-cron-hourly.conf
++exec /usr/sbin/yum-cron /etc/yum/yum-cron-hourly.conf
 diff --git a/yum-updatesd.py b/yum-updatesd.py
 old mode 100644
 new mode 100755
@@ -185435,7 +185483,7 @@ index 1ce4720..2f3f7a3
      gobject.threads_init()
      dbus.glib.threads_init()
 diff --git a/yum.spec b/yum.spec
-index abd203f..a270de5 100644
+index abd203f..455c3ae 100644
 --- a/yum.spec
 +++ b/yum.spec
 @@ -1,24 +1,78 @@
@@ -185523,7 +185571,7 @@ index abd203f..a270de5 100644
  Conflicts: rpm >= 5-0
  # Zif is a re-implementation of yum in C, however:
  #
-@@ -34,18 +88,30 @@ Conflicts: rpm >= 5-0
+@@ -34,18 +88,32 @@ Conflicts: rpm >= 5-0
  # zif experts).
  #
  # ...so we have two sane choices: i) Conflict with it. 2) Stop developing yum.
@@ -185556,12 +185604,14 @@ index abd203f..a270de5 100644
 +Provides: yum-plugin-downloadonly = 3.4.3-44.yum
 +Obsoletes: yum-presto < 3.4.3-66.yum
 +Provides: yum-presto = 3.4.3-66.yum
++Obsoletes: yum-plugin-security < 1.1.32
++Provides: yum-plugin-security = 3.4.3-84.yum
 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 +
  
  %description
  Yum is a utility that can check for and automatically download and
-@@ -58,9 +124,11 @@ Group: Applications/System
+@@ -58,9 +126,11 @@ Group: Applications/System
  Requires: yum = %{version}-%{release}
  Requires: dbus-python
  Requires: pygobject2
@@ -185575,7 +185625,7 @@ index abd203f..a270de5 100644
  Requires(postun): /sbin/service
  
  
-@@ -68,33 +136,74 @@ Requires(postun): /sbin/service
+@@ -68,33 +138,74 @@ Requires(postun): /sbin/service
  yum-updatesd provides a daemon which checks for available updates and 
  can notify you when they are available via email, syslog or dbus. 
  
@@ -185584,7 +185634,7 @@ index abd203f..a270de5 100644
  Summary: Files needed to run yum updates as a cron job
  Group: System Environment/Base
 -Requires: yum >= 3.0 vixie-cron crontabs yum-plugin-downloadonly findutils
-+Requires: yum >= 3.0 cronie crontabs findutils
++Requires: yum >= 3.4.3-84 cronie crontabs findutils
 +%if %{yum_cron_systemd}
 +BuildRequires: systemd-units
 +Requires(post): systemd
@@ -185655,7 +185705,7 @@ index abd203f..a270de5 100644
  
  # Ghost files:
  mkdir -p $RPM_BUILD_ROOT/var/lib/yum/history
-@@ -102,12 +211,26 @@ mkdir -p $RPM_BUILD_ROOT/var/lib/yum/plugins
+@@ -102,12 +213,26 @@ mkdir -p $RPM_BUILD_ROOT/var/lib/yum/plugins
  mkdir -p $RPM_BUILD_ROOT/var/lib/yum/yumdb
  touch $RPM_BUILD_ROOT/var/lib/yum/uuid
  
@@ -185682,7 +185732,7 @@ index abd203f..a270de5 100644
  %post updatesd
  /sbin/chkconfig --add yum-updatesd
  /sbin/service yum-updatesd condrestart >/dev/null 2>&1
-@@ -119,9 +242,29 @@ if [ $1 = 0 ]; then
+@@ -119,9 +244,29 @@ if [ $1 = 0 ]; then
   /sbin/service yum-updatesd stop >/dev/null 2>&1
  fi
  exit 0
@@ -185713,7 +185763,7 @@ index abd203f..a270de5 100644
  # Make sure chkconfig knows about the service
  /sbin/chkconfig --add yum-cron
  # if an upgrade:
-@@ -144,8 +287,13 @@ if [ "$1" -ge "1" ]; then
+@@ -144,8 +289,13 @@ if [ "$1" -ge "1" ]; then
   fi
  fi 
  exit 0
@@ -185727,7 +185777,7 @@ index abd203f..a270de5 100644
  # if this will be a complete removeal of yum-cron rather than an upgrade,
  # remove the service from chkconfig control
  if [ $1 = 0 ]; then
-@@ -153,33 +301,48 @@ if [ $1 = 0 ]; then
+@@ -153,33 +303,48 @@ if [ $1 = 0 ]; then
   /sbin/service yum-cron stop 1> /dev/null 2>&1
  fi
  exit 0
@@ -185783,7 +185833,7 @@ index abd203f..a270de5 100644
  %dir /var/cache/yum
  %dir /var/lib/yum
  %ghost /var/lib/yum/uuid
-@@ -188,20 +351,27 @@ exit 0
+@@ -188,20 +353,27 @@ exit 0
  %ghost /var/lib/yum/yumdb
  %{_mandir}/man*/yum.*
  %{_mandir}/man*/yum-shell*
@@ -185819,7 +185869,7 @@ index abd203f..a270de5 100644
  %files updatesd
  %defattr(-, root, root)
  %config(noreplace) %{_sysconfdir}/yum/yum-updatesd.conf
-@@ -210,8 +380,12 @@ exit 0
+@@ -210,8 +382,12 @@ exit 0
  %{_datadir}/yum-cli/yumupd.py*
  %{_sbindir}/yum-updatesd
  %{_mandir}/man*/yum-updatesd*
@@ -185860,7 +185910,7 @@ index c1af4ad..e3e3956 100644
      pass
      
 diff --git a/yum/__init__.py b/yum/__init__.py
-index 99039e0..d1ab41a 100644
+index 99039e0..766f960 100644
 --- a/yum/__init__.py
 +++ b/yum/__init__.py
 @@ -21,6 +21,7 @@ The Yum RPM software updater.
@@ -185887,15 +185937,16 @@ index 99039e0..d1ab41a 100644
  
  import config
  from config import ParsingError, ConfigParser
-@@ -73,6 +79,7 @@ import logginglevels
+@@ -73,6 +79,8 @@ import logginglevels
  import yumRepo
  import callbacks
  import yum.history
 +import yum.igroups
++import update_md
  
  import warnings
  warnings.simplefilter("ignore", Errors.YumFutureDeprecationWarning)
-@@ -82,7 +89,8 @@ from packages import YumAvailablePackage, YumLocalPackage, YumInstalledPackage
+@@ -82,7 +90,8 @@ from packages import YumAvailablePackage, YumLocalPackage, YumInstalledPackage
  from packages import YumUrlPackage, YumNotFoundPackage
  from constants import *
  from yum.rpmtrans import RPMTransaction,SimpleCliCallBack
@@ -185905,7 +185956,7 @@ index 99039e0..d1ab41a 100644
  
  import string
  import StringIO
-@@ -102,10 +110,12 @@ default_grabber.opts.user_agent += " yum/" + __version__
+@@ -102,10 +111,12 @@ default_grabber.opts.user_agent += " yum/" + __version__
  
  
  class _YumPreBaseConf:
@@ -185922,7 +185973,7 @@ index 99039e0..d1ab41a 100644
      def __init__(self):
          self.fn = '/etc/yum/yum.conf'
          self.root = '/'
-@@ -125,12 +135,15 @@ class _YumPreBaseConf:
+@@ -125,12 +136,15 @@ class _YumPreBaseConf:
  
  
  class _YumPreRepoConf:
@@ -185942,7 +185993,7 @@ index 99039e0..d1ab41a 100644
          self.callback = None
          self.failure_callback = None
          self.interrupt_callback = None
-@@ -164,11 +177,11 @@ class _YumCostExclude:
+@@ -164,11 +178,11 @@ class _YumCostExclude:
          return False
  
  class YumBase(depsolve.Depsolve):
@@ -185959,7 +186010,7 @@ index 99039e0..d1ab41a 100644
      def __init__(self):
          depsolve.Depsolve.__init__(self)
          self._conf = None
-@@ -177,6 +190,7 @@ class YumBase(depsolve.Depsolve):
+@@ -177,9 +191,11 @@ class YumBase(depsolve.Depsolve):
          self._up = None
          self._comps = None
          self._history = None
@@ -185967,15 +186018,21 @@ index 99039e0..d1ab41a 100644
          self._pkgSack = None
          self._lockfile = None
          self._tags = None
-@@ -204,6 +218,7 @@ class YumBase(depsolve.Depsolve):
++        self._upinfo = None
+         self._ts_save_file = None
+         self.skipped_packages = []   # packages skip by the skip-broken code
+         self._not_found_a = {}
+@@ -204,6 +220,9 @@ class YumBase(depsolve.Depsolve):
  
          self.run_with_package_names = set()
          self._cleanup = []
 +        self.exit_code = 0
++
++        self.updateinfo_filters = {}
  
      def __del__(self):
          self.close()
-@@ -213,10 +228,15 @@ class YumBase(depsolve.Depsolve):
+@@ -213,10 +232,15 @@ class YumBase(depsolve.Depsolve):
          for cb in self._cleanup: cb()
  
      def close(self):
@@ -185991,7 +186048,7 @@ index 99039e0..d1ab41a 100644
          if self._repos:
              self._repos.close()
  
-@@ -225,15 +245,33 @@ class YumBase(depsolve.Depsolve):
+@@ -225,15 +249,33 @@ class YumBase(depsolve.Depsolve):
          return transactioninfo.TransactionData()
  
      def doGenericSetup(self, cache=0):
@@ -186027,7 +186084,7 @@ index 99039e0..d1ab41a 100644
          warnings.warn(_('doConfigSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -297,15 +335,17 @@ class YumBase(depsolve.Depsolve):
+@@ -297,15 +339,17 @@ class YumBase(depsolve.Depsolve):
              # Try the old default
              fn = '/etc/yum.conf'
  
@@ -186048,7 +186105,7 @@ index 99039e0..d1ab41a 100644
  
          if debuglevel != None:
              startupconf.debuglevel = debuglevel
-@@ -336,6 +376,12 @@ class YumBase(depsolve.Depsolve):
+@@ -336,6 +380,12 @@ class YumBase(depsolve.Depsolve):
  
          self._conf = config.readMainConfig(startupconf)
  
@@ -186061,7 +186118,7 @@ index 99039e0..d1ab41a 100644
          #  We don't want people accessing/altering preconf after it becomes
          # worthless. So we delete it, and thus. it'll raise AttributeError
          del self.preconf
-@@ -367,22 +413,36 @@ class YumBase(depsolve.Depsolve):
+@@ -367,22 +417,36 @@ class YumBase(depsolve.Depsolve):
      def doLoggingSetup(self, debuglevel, errorlevel,
                         syslog_ident=None, syslog_facility=None,
                         syslog_device='/dev/log'):
@@ -186105,7 +186162,7 @@ index 99039e0..d1ab41a 100644
          if repo_age is None:
              repo_age = os.stat(repofn)[8]
          
-@@ -391,8 +451,7 @@ class YumBase(depsolve.Depsolve):
+@@ -391,8 +455,7 @@ class YumBase(depsolve.Depsolve):
          try:
              parser.readfp(confpp_obj)
          except ParsingError, e:
@@ -186115,7 +186172,7 @@ index 99039e0..d1ab41a 100644
  
          # Check sections in the .repo file that was just slurped up
          for section in parser.sections():
-@@ -429,7 +488,15 @@ class YumBase(depsolve.Depsolve):
+@@ -429,7 +492,15 @@ class YumBase(depsolve.Depsolve):
  
                  thisrepo.base_persistdir = self.conf._repos_persistdir
  
@@ -186132,7 +186189,7 @@ index 99039e0..d1ab41a 100644
              if thisrepo.id in self.repo_setopts:
                  for opt in self.repo_setopts[thisrepo.id].items:
                      if not hasattr(thisrepo, opt):
-@@ -440,6 +507,20 @@ class YumBase(depsolve.Depsolve):
+@@ -440,6 +511,20 @@ class YumBase(depsolve.Depsolve):
              if validate and not validate(thisrepo):
                  continue
                      
@@ -186153,7 +186210,7 @@ index 99039e0..d1ab41a 100644
              # Got our list of repo objects, add them to the repos
              # collection
              try:
-@@ -448,8 +529,11 @@ class YumBase(depsolve.Depsolve):
+@@ -448,8 +533,11 @@ class YumBase(depsolve.Depsolve):
                  self.logger.warning(e)
          
      def getReposFromConfig(self):
@@ -186167,7 +186224,7 @@ index 99039e0..d1ab41a 100644
          # Read .repo files from directories specified by the reposdir option
          # (typically /etc/yum/repos.d)
          repo_config_age = self.conf.config_file_age
-@@ -466,18 +550,22 @@ class YumBase(depsolve.Depsolve):
+@@ -466,18 +554,22 @@ class YumBase(depsolve.Depsolve):
  
              if os.path.isdir(reposdir):
                  for repofn in sorted(glob.glob('%s/*.repo' % reposdir)):
@@ -186195,7 +186252,7 @@ index 99039e0..d1ab41a 100644
          repo = yumRepo.YumRepository(section)
          try:
              repo.populate(parser, section, self.conf)
-@@ -493,38 +581,40 @@ class YumBase(depsolve.Depsolve):
+@@ -493,38 +585,40 @@ class YumBase(depsolve.Depsolve):
          repo.name = to_unicode(repo.name)
  
          # Set attributes not from the config file
@@ -186258,7 +186315,7 @@ index 99039e0..d1ab41a 100644
          if isinstance(self.plugins, plugins.YumPlugins):
              raise RuntimeError(_("plugins already initialised"))
  
-@@ -533,6 +623,8 @@ class YumBase(depsolve.Depsolve):
+@@ -533,6 +627,8 @@ class YumBase(depsolve.Depsolve):
  
      
      def doRpmDBSetup(self):
@@ -186267,7 +186324,7 @@ index 99039e0..d1ab41a 100644
          warnings.warn(_('doRpmDBSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -552,7 +644,8 @@ class YumBase(depsolve.Depsolve):
+@@ -552,7 +648,8 @@ class YumBase(depsolve.Depsolve):
          return self._rpmdb
  
      def closeRpmDB(self):
@@ -186277,7 +186334,7 @@ index 99039e0..d1ab41a 100644
          if self._rpmdb is not None:
              self._rpmdb.ts = None
              self._rpmdb.dropCachedData()
-@@ -567,6 +660,12 @@ class YumBase(depsolve.Depsolve):
+@@ -567,6 +664,12 @@ class YumBase(depsolve.Depsolve):
          self._ts = None
  
      def doRepoSetup(self, thisrepo=None):
@@ -186290,7 +186347,7 @@ index 99039e0..d1ab41a 100644
          warnings.warn(_('doRepoSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -588,7 +687,8 @@ class YumBase(depsolve.Depsolve):
+@@ -588,7 +691,8 @@ class YumBase(depsolve.Depsolve):
              prerepoconf = self.prerepoconf
              del self.prerepoconf
  
@@ -186300,7 +186357,7 @@ index 99039e0..d1ab41a 100644
              self.repos.callback = prerepoconf.callback
              self.repos.setFailureCallback(prerepoconf.failure_callback)
              self.repos.setInterruptCallback(prerepoconf.interrupt_callback)
-@@ -602,24 +702,6 @@ class YumBase(depsolve.Depsolve):
+@@ -602,24 +706,6 @@ class YumBase(depsolve.Depsolve):
  
  
          if doSetup:
@@ -186325,7 +186382,7 @@ index 99039e0..d1ab41a 100644
              repo_st = time.time()        
              self._repos.doSetup(thisrepo)
              self.verbose_logger.debug('repo time: %0.3f' % (time.time() - repo_st))        
-@@ -630,6 +712,14 @@ class YumBase(depsolve.Depsolve):
+@@ -630,6 +716,14 @@ class YumBase(depsolve.Depsolve):
          self._repos = RepoStorage(self)
      
      def doSackSetup(self, archlist=None, thisrepo=None):
@@ -186340,7 +186397,7 @@ index 99039e0..d1ab41a 100644
          warnings.warn(_('doSackSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -711,6 +801,9 @@ class YumBase(depsolve.Depsolve):
+@@ -711,6 +805,9 @@ class YumBase(depsolve.Depsolve):
              
             
      def doUpdateSetup(self):
@@ -186350,7 +186407,7 @@ index 99039e0..d1ab41a 100644
          warnings.warn(_('doUpdateSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -765,6 +858,8 @@ class YumBase(depsolve.Depsolve):
+@@ -765,6 +862,8 @@ class YumBase(depsolve.Depsolve):
          return self._up
      
      def doGroupSetup(self):
@@ -186359,7 +186416,7 @@ index 99039e0..d1ab41a 100644
          warnings.warn(_('doGroupSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -820,16 +915,14 @@ class YumBase(depsolve.Depsolve):
+@@ -820,16 +919,14 @@ class YumBase(depsolve.Depsolve):
              self.verbose_logger.log(logginglevels.DEBUG_4,
                  _('Adding group file from repository: %s'), repo)
              groupfile = repo.getGroups()
@@ -186381,7 +186438,7 @@ index 99039e0..d1ab41a 100644
                  self.logger.critical(msg)
              else:
                  repo.groups_added = True
-@@ -837,7 +930,10 @@ class YumBase(depsolve.Depsolve):
+@@ -837,7 +934,10 @@ class YumBase(depsolve.Depsolve):
          if self._comps.compscount == 0:
              raise Errors.GroupsError, _('No Groups Available in any repository')
  
@@ -186393,7 +186450,7 @@ index 99039e0..d1ab41a 100644
          self.verbose_logger.debug('group time: %0.3f' % (time.time() - group_st))                
          return self._comps
  
-@@ -868,7 +964,7 @@ class YumBase(depsolve.Depsolve):
+@@ -868,22 +968,60 @@ class YumBase(depsolve.Depsolve):
                      # feed it into _tags.add()
                      self._tags.add(repo.id, tag_sqlite)
                  except (Errors.RepoError, Errors.PkgTagsError), e:
@@ -186402,7 +186459,41 @@ index 99039e0..d1ab41a 100644
                      self.logger.critical(msg)
                      
                  
-@@ -881,9 +977,18 @@ class YumBase(depsolve.Depsolve):
+         self.verbose_logger.debug('tags time: %0.3f' % (time.time() - tag_st))
+         return self._tags
+         
++
++    def _getUpdateinfo(self):
++        """ create the Update Info object used to search/report the updateinfo
++            metadata"""
++
++        upi_st = time.time()
++        self.verbose_logger.log(logginglevels.DEBUG_4,
++                                _('Getting updateinfo metadata'))
++
++        if self._upinfo is None:
++            self._upinfo = update_md.UpdateMetadata()
++
++            for repo in self.repos.listEnabled():
++                if 'updateinfo' not in repo.repoXML.fileTypes():
++                    continue
++
++                self.verbose_logger.log(logginglevels.DEBUG_4,
++                    _('Adding Update Info from repository: %s'), repo)
++
++                try:
++                    self._upinfo.add(repo)
++                except Errors.RepoMDError, e:
++                    msg = _('Failed to add Update Info for repository: %s - %s') % (repo, exception2msg(e))
++                    self.logger.critical(msg)
++
++        self.verbose_logger.debug('updateinfo time: %0.3f' %
++                                  (time.time() - upi_st))
++        return self._upinfo
++
+     def _getHistory(self):
+         """auto create the history object that to access/append the transaction
+            history information. """
          if self._history is None:
              pdb_path = self.conf.persistdir + "/history"
              self._history = yum.history.YumHistory(root=self.conf.installroot,
@@ -186422,7 +186513,7 @@ index 99039e0..d1ab41a 100644
      # properties so they auto-create themselves with defaults
      repos = property(fget=lambda self: self._getRepos(),
                       fset=lambda self, value: setattr(self, "_repos", value),
-@@ -921,6 +1026,11 @@ class YumBase(depsolve.Depsolve):
+@@ -921,16 +1059,27 @@ class YumBase(depsolve.Depsolve):
                         fdel=lambda self: setattr(self, "_history", None),
                         doc="Yum History Object")
  
@@ -186434,7 +186525,12 @@ index 99039e0..d1ab41a 100644
      pkgtags = property(fget=lambda self: self._getTags(),
                         fset=lambda self, value: setattr(self, "_tags",value),
                         fdel=lambda self: setattr(self, "_tags", None),
-@@ -928,9 +1038,10 @@ class YumBase(depsolve.Depsolve):
+                        doc="Yum Package Tags Object")
++
++    upinfo = property(fget=lambda self: self._getUpdateinfo(),
++                      fset=lambda self, value: setattr(self, "_upinfo", value),
++                      fdel=lambda self: setattr(self, "_upinfo", None),
++                      doc="Yum Update Info Object")
      
      
      def doSackFilelistPopulate(self):
@@ -186448,7 +186544,7 @@ index 99039e0..d1ab41a 100644
          necessary = False
          
          # I can't think of a nice way of doing this, we have to have the sack here
-@@ -951,8 +1062,12 @@ class YumBase(depsolve.Depsolve):
+@@ -951,8 +1100,12 @@ class YumBase(depsolve.Depsolve):
              self.repos.populateSack(mdtype='filelists')
             
      def yumUtilsMsg(self, func, prog):
@@ -186463,7 +186559,7 @@ index 99039e0..d1ab41a 100644
          if self.rpmdb.contains(name="yum-utils"):
              return
  
-@@ -964,8 +1079,17 @@ class YumBase(depsolve.Depsolve):
+@@ -964,8 +1117,17 @@ class YumBase(depsolve.Depsolve):
               (hibeg, prog, hiend))
  
      def buildTransaction(self, unfinished_transactions_check=True):
@@ -186483,7 +186579,7 @@ index 99039e0..d1ab41a 100644
          if (unfinished_transactions_check and
              misc.find_unfinished_transactions(yumlibpath=self.conf.persistdir)):
              msg = _('There are unfinished transactions remaining. You might ' \
-@@ -1004,7 +1128,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1004,7 +1166,7 @@ class YumBase(depsolve.Depsolve):
              # If transaction was changed by postresolve plugins then we should run skipbroken again
              (rescode, restring) = self._doSkipBroken(rescode, restring, clear_skipped=False )
  
@@ -186492,7 +186588,7 @@ index 99039e0..d1ab41a 100644
              self.tsInfo.pkgSack.dropCachedData()
  
          # FIXME: This is horrible, see below and yummain. Maybe create a real
-@@ -1044,6 +1168,39 @@ class YumBase(depsolve.Depsolve):
+@@ -1044,6 +1206,39 @@ class YumBase(depsolve.Depsolve):
                  if first.verEQ(other):
                      continue
                  msg = _('Protected multilib versions: %s != %s')
@@ -186532,7 +186628,7 @@ index 99039e0..d1ab41a 100644
                  xrestring.append(msg % (first, other))
          if xrestring:
              rescode = 1
-@@ -1227,7 +1384,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1227,7 +1422,7 @@ class YumBase(depsolve.Depsolve):
                  self.verbose_logger.info(msg)
              self.skipped_packages.extend(skipped_list)   # make the skipped packages public
          else:
@@ -186541,7 +186637,7 @@ index 99039e0..d1ab41a 100644
              self.verbose_logger.info("Skip-broken could not solve problems")
              return 1, orig_restring
          return rescode, restring
-@@ -1242,13 +1399,15 @@ class YumBase(depsolve.Depsolve):
+@@ -1242,13 +1437,15 @@ class YumBase(depsolve.Depsolve):
          if None in pkgtup:
              return None
          return pkgtup
@@ -186561,7 +186657,7 @@ index 99039e0..d1ab41a 100644
          if pkgtup is None:
              return
          self._not_found_i[pkgtup] = YumNotFoundPackage(pkgtup)
-@@ -1267,7 +1426,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1267,7 +1464,7 @@ class YumBase(depsolve.Depsolve):
              for pkg in txmbr.obsoleted_by:
                  # check if the obsoleting txmbr is in the transaction
                  # else remove the obsoleted txmbr
@@ -186570,7 +186666,7 @@ index 99039e0..d1ab41a 100644
                  if not self.tsInfo.exists(pkg.pkgtup):
                      self.verbose_logger.debug('SKIPBROKEN: Remove extra obsoleted %s (%s)' % (txmbr.po,pkg) )
                      self.tsInfo.remove(txmbr.po.pkgtup)
-@@ -1282,7 +1441,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1282,7 +1479,7 @@ class YumBase(depsolve.Depsolve):
              for pkg in txmbr.updated_by:
                  # check if the updating txmbr is in the transaction
                  # else remove the updated txmbr
@@ -186579,7 +186675,7 @@ index 99039e0..d1ab41a 100644
                  if not self.tsInfo.exists(pkg.pkgtup):
                      self.verbose_logger.debug('SKIPBROKEN: Remove extra updated %s (%s)' % (txmbr.po,pkg) )
                      self.tsInfo.remove(txmbr.po.pkgtup)
-@@ -1379,9 +1538,19 @@ class YumBase(depsolve.Depsolve):
+@@ -1379,9 +1576,19 @@ class YumBase(depsolve.Depsolve):
  
      def _getDepsToRemove(self,po, deptree, toRemove):
          for dep in deptree.get(po, []): # Loop trough all deps of po
@@ -186599,7 +186695,7 @@ index 99039e0..d1ab41a 100644
              toRemove.add(dep)
              self._getDepsToRemove(dep, deptree, toRemove)
  
-@@ -1454,8 +1623,14 @@ class YumBase(depsolve.Depsolve):
+@@ -1454,8 +1661,14 @@ class YumBase(depsolve.Depsolve):
          return probs
  
      def runTransaction(self, cb):
@@ -186615,7 +186711,7 @@ index 99039e0..d1ab41a 100644
          self.plugins.run('pretrans')
  
          #  We may want to put this other places, eventually, but for now it's
-@@ -1516,10 +1691,23 @@ class YumBase(depsolve.Depsolve):
+@@ -1516,10 +1729,23 @@ class YumBase(depsolve.Depsolve):
                  pass
          self._ts_save_file = None
          
@@ -186639,7 +186735,7 @@ index 99039e0..d1ab41a 100644
          
          # make resultobject - just a plain yumgenericholder object
          resultobject = misc.GenericHolder()
-@@ -1567,13 +1755,24 @@ class YumBase(depsolve.Depsolve):
+@@ -1567,13 +1793,24 @@ class YumBase(depsolve.Depsolve):
          self.plugins.run('posttrans')
          # sync up what just happened versus what is in the rpmdb
          if not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST):
@@ -186669,7 +186765,7 @@ index 99039e0..d1ab41a 100644
          # check to see that the rpmdb and the tsInfo roughly matches
          # push package object metadata outside of rpmdb into yumdb
          # delete old yumdb metadata entries
-@@ -1584,9 +1783,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1584,9 +1821,16 @@ class YumBase(depsolve.Depsolve):
          #    that there is not also an install of this pkg in the tsInfo (reinstall)
          # for any kind of install add from_repo to the yumdb, and the cmdline
          # and the install reason
@@ -186686,7 +186782,7 @@ index 99039e0..d1ab41a 100644
          for txmbr in self.tsInfo:
              if txmbr.output_state in TS_INSTALL_STATES:
                  if not self.rpmdb.contains(po=txmbr.po):
-@@ -1596,12 +1802,18 @@ class YumBase(depsolve.Depsolve):
+@@ -1596,12 +1840,18 @@ class YumBase(depsolve.Depsolve):
                                             ' but is not!' % txmbr.po))
                      # Note: Get Panu to do te.Failed() so we don't have to
                      txmbr.output_state = TS_FAILED
@@ -186705,7 +186801,7 @@ index 99039e0..d1ab41a 100644
                  if hasattr(self, 'args') and self.args:
                      po.yumdb_info.command_line = ' '.join(self.args)
                  elif hasattr(self, 'cmds') and self.cmds:
-@@ -1630,6 +1842,10 @@ class YumBase(depsolve.Depsolve):
+@@ -1630,6 +1880,10 @@ class YumBase(depsolve.Depsolve):
                      if md:
                          po.yumdb_info.from_repo_timestamp = str(md.timestamp)
  
@@ -186716,7 +186812,7 @@ index 99039e0..d1ab41a 100644
                  loginuid = misc.getloginuid()
                  if txmbr.updates or txmbr.downgrades or txmbr.reinstall:
                      if txmbr.updates:
-@@ -1640,11 +1856,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1640,11 +1894,16 @@ class YumBase(depsolve.Depsolve):
                          opo = po
                      if 'installed_by' in opo.yumdb_info:
                          po.yumdb_info.installed_by = opo.yumdb_info.installed_by
@@ -186733,7 +186829,7 @@ index 99039e0..d1ab41a 100644
          # Remove old ones after installing new ones, so we can copy values.
          for txmbr in self.tsInfo:
              if txmbr.output_state in TS_INSTALL_STATES:
-@@ -1662,10 +1883,13 @@ class YumBase(depsolve.Depsolve):
+@@ -1662,10 +1921,13 @@ class YumBase(depsolve.Depsolve):
                                                 ' but is not!' % txmbr.po))
                          # Note: Get Panu to do te.Failed() so we don't have to
                          txmbr.output_state = TS_FAILED
@@ -186747,7 +186843,7 @@ index 99039e0..d1ab41a 100644
                  self.verbose_logger.log(logginglevels.DEBUG_2, 'What is this? %s' % txmbr.po)
  
          self.plugins.run('postverifytrans')
-@@ -1680,10 +1904,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1680,10 +1942,11 @@ class YumBase(depsolve.Depsolve):
          self.verbose_logger.debug('VerifyTransaction time: %0.3f' % (time.time() - vt_st))
  
      def costExcludePackages(self):
@@ -186763,7 +186859,7 @@ index 99039e0..d1ab41a 100644
          # if all the repo.costs are equal then don't bother running things
          costs = {}
          for r in self.repos.listEnabled():
-@@ -1705,10 +1930,12 @@ class YumBase(depsolve.Depsolve):
+@@ -1705,10 +1968,12 @@ class YumBase(depsolve.Depsolve):
              done = True
  
      def excludePackages(self, repo=None):
@@ -186779,7 +186875,7 @@ index 99039e0..d1ab41a 100644
          if "all" in self.conf.disable_excludes:
              return
          
-@@ -1735,9 +1962,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1735,9 +2000,11 @@ class YumBase(depsolve.Depsolve):
              self.pkgSack.addPackageExcluder(repoid, exid,'exclude.match', match)
  
      def includePackages(self, repo):
@@ -186794,7 +186890,7 @@ index 99039e0..d1ab41a 100644
          includelist = repo.getIncludePkgList()
          
          if len(includelist) == 0:
-@@ -1757,8 +1986,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1757,8 +2024,11 @@ class YumBase(depsolve.Depsolve):
          self.pkgSack.addPackageExcluder(repo.id, exid, 'exclude.marked')
          
      def doLock(self, lockfile = YUM_PID_FILE):
@@ -186808,7 +186904,7 @@ index 99039e0..d1ab41a 100644
          if self.conf.uid != 0:
              #  If we are a user, assume we are using the root cache ... so don't
              # bother locking.
-@@ -1774,38 +2006,26 @@ class YumBase(depsolve.Depsolve):
+@@ -1774,38 +2044,26 @@ class YumBase(depsolve.Depsolve):
          
          mypid=str(os.getpid())    
          while not self._lock(lockfile, mypid, 0644):
@@ -186862,7 +186958,7 @@ index 99039e0..d1ab41a 100644
          # if we're not root then we don't lock - just return nicely
          #  Note that we can get here from __del__, so if we haven't created
          # YumBase.conf we don't want to do so here as creating stuff inside
-@@ -1830,31 +2050,69 @@ class YumBase(depsolve.Depsolve):
+@@ -1830,31 +2088,69 @@ class YumBase(depsolve.Depsolve):
          self._unlock(lockfile)
          self._lockfile = None
          
@@ -186943,7 +187039,7 @@ index 99039e0..d1ab41a 100644
          failed = False
  
          if type(fo) is types.InstanceType:
-@@ -1894,9 +2152,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1894,9 +2190,16 @@ class YumBase(depsolve.Depsolve):
          
          
      def verifyChecksum(self, fo, checksumType, csum):
@@ -186963,7 +187059,7 @@ index 99039e0..d1ab41a 100644
          try:
              filesum = misc.checksum(checksumType, fo)
          except Errors.MiscError, e:
-@@ -1908,13 +2173,26 @@ class YumBase(depsolve.Depsolve):
+@@ -1908,13 +2211,26 @@ class YumBase(depsolve.Depsolve):
          return 0
  
      def downloadPkgs(self, pkglist, callback=None, callback_total=None):
@@ -186991,7 +187087,7 @@ index 99039e0..d1ab41a 100644
              if a is None:
                  return -1
              if b is None:
-@@ -1925,9 +2203,6 @@ class YumBase(depsolve.Depsolve):
+@@ -1925,9 +2241,6 @@ class YumBase(depsolve.Depsolve):
                  return 1
              return 0
          
@@ -187001,7 +187097,7 @@ index 99039e0..d1ab41a 100644
          errors = {}
          def adderror(po, msg):
              errors.setdefault(po, []).append(msg)
-@@ -1943,116 +2218,194 @@ class YumBase(depsolve.Depsolve):
+@@ -1943,116 +2256,194 @@ class YumBase(depsolve.Depsolve):
          self.history.close()
  
          self.plugins.run('predownload', pkglist=pkglist)
@@ -187285,7 +187381,7 @@ index 99039e0..d1ab41a 100644
          if type(fo) is types.InstanceType:
              fo = fo.filename
              
-@@ -2076,9 +2429,12 @@ class YumBase(depsolve.Depsolve):
+@@ -2076,9 +2467,12 @@ class YumBase(depsolve.Depsolve):
          return 1
          
      def downloadHeader(self, po):
@@ -187300,7 +187396,7 @@ index 99039e0..d1ab41a 100644
          if hasattr(po, 'pkgtype') and po.pkgtype == 'local':
              return
                  
-@@ -2122,15 +2478,17 @@ class YumBase(depsolve.Depsolve):
+@@ -2122,15 +2516,17 @@ class YumBase(depsolve.Depsolve):
              return
  
      def sigCheckPkg(self, po):
@@ -187326,7 +187422,7 @@ index 99039e0..d1ab41a 100644
          if self._override_sigchecks:
              check = False
              hasgpgkey = 0
-@@ -2181,6 +2539,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2181,6 +2577,9 @@ class YumBase(depsolve.Depsolve):
          return result, msg
  
      def cleanUsedHeadersPackages(self):
@@ -187336,7 +187432,7 @@ index 99039e0..d1ab41a 100644
          filelist = []
          for txmbr in self.tsInfo:
              if txmbr.po.state not in TS_INSTALL_STATES:
-@@ -2218,27 +2579,42 @@ class YumBase(depsolve.Depsolve):
+@@ -2218,27 +2617,42 @@ class YumBase(depsolve.Depsolve):
                      _('%s removed'), fn)
          
      def cleanHeaders(self):
@@ -187381,7 +187477,7 @@ index 99039e0..d1ab41a 100644
          cachedir = self.conf.persistdir + "/rpmdb-indexes/"
          if not os.path.exists(cachedir):
              filelist = []
-@@ -2271,9 +2647,31 @@ class YumBase(depsolve.Depsolve):
+@@ -2271,9 +2685,31 @@ class YumBase(depsolve.Depsolve):
          return 0, [msg]
  
      def doPackageLists(self, pkgnarrow='all', patterns=None, showdups=None,
@@ -187416,7 +187512,7 @@ index 99039e0..d1ab41a 100644
          if showdups is None:
              showdups = self.conf.showdupesfromrepos
          ygh = misc.GenericHolder(iter=pkgnarrow)
-@@ -2295,6 +2693,8 @@ class YumBase(depsolve.Depsolve):
+@@ -2295,6 +2731,8 @@ class YumBase(depsolve.Depsolve):
              ndinst = {} # Newest versions by name.arch
              for po in self.rpmdb.returnPackages(patterns=patterns,
                                                  ignore_case=ic):
@@ -187425,7 +187521,7 @@ index 99039e0..d1ab41a 100644
                  dinst[po.pkgtup] = po
                  if showdups:
                      continue
-@@ -2304,8 +2704,13 @@ class YumBase(depsolve.Depsolve):
+@@ -2304,8 +2742,13 @@ class YumBase(depsolve.Depsolve):
              installed = dinst.values()
                          
              if showdups:
@@ -187440,7 +187536,7 @@ index 99039e0..d1ab41a 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2323,16 +2728,30 @@ class YumBase(depsolve.Depsolve):
+@@ -2323,16 +2766,30 @@ class YumBase(depsolve.Depsolve):
                      key = (pkg.name, pkg.arch)
                      if pkg.pkgtup in dinst:
                          reinstall_available.append(pkg)
@@ -187474,7 +187570,7 @@ index 99039e0..d1ab41a 100644
                  if len(matches) > 1:
                      updates.append(matches[0])
                      self.verbose_logger.log(logginglevels.DEBUG_1,
-@@ -2352,13 +2771,19 @@ class YumBase(depsolve.Depsolve):
+@@ -2352,13 +2809,19 @@ class YumBase(depsolve.Depsolve):
          elif pkgnarrow == 'installed':
              installed = self.rpmdb.returnPackages(patterns=patterns,
                                                    ignore_case=ic)
@@ -187495,7 +187591,7 @@ index 99039e0..d1ab41a 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2392,9 +2817,21 @@ class YumBase(depsolve.Depsolve):
+@@ -2392,9 +2855,21 @@ class YumBase(depsolve.Depsolve):
              avail = set(avail)
              for po in self.rpmdb.returnPackages(patterns=patterns,
                                                  ignore_case=ic):
@@ -187517,7 +187613,7 @@ index 99039e0..d1ab41a 100644
          # obsoleting packages (and what they obsolete)
          elif pkgnarrow == 'obsoletes':
              self.conf.obsoletes = 1
-@@ -2402,6 +2839,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2402,6 +2877,7 @@ class YumBase(depsolve.Depsolve):
              for (pkgtup, instTup) in self.up.getObsoletesTuples():
                  (n,a,e,v,r) = pkgtup
                  pkgs = self.pkgSack.searchNevra(name=n, arch=a, ver=v, rel=r, epoch=e)
@@ -187525,7 +187621,7 @@ index 99039e0..d1ab41a 100644
                  instpo = self.getInstalledPackageObject(instTup)
                  for po in pkgs:
                      obsoletes.append(po)
-@@ -2433,7 +2871,12 @@ class YumBase(depsolve.Depsolve):
+@@ -2433,7 +2909,12 @@ class YumBase(depsolve.Depsolve):
              recentlimit = now-(self.conf.recent*86400)
              if showdups:
                  avail = self.pkgSack.returnPackages(patterns=patterns,
@@ -187539,7 +187635,7 @@ index 99039e0..d1ab41a 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2461,14 +2904,13 @@ class YumBase(depsolve.Depsolve):
+@@ -2461,14 +2942,13 @@ class YumBase(depsolve.Depsolve):
  
          
      def findDeps(self, pkgs):
@@ -187559,7 +187655,7 @@ index 99039e0..d1ab41a 100644
          results = {}
  
          for pkg in pkgs:
-@@ -2495,10 +2937,22 @@ class YumBase(depsolve.Depsolve):
+@@ -2495,10 +2975,22 @@ class YumBase(depsolve.Depsolve):
      # pre 3.2.10 API used to always showdups, so that's the default atm.
      def searchGenerator(self, fields, criteria, showdups=True, keys=False, 
                                               searchtags=True, searchrpmdb=True):
@@ -187586,7 +187682,7 @@ index 99039e0..d1ab41a 100644
          sql_fields = []
          for f in fields:
              sql_fields.append(RPM_TO_SQLITE.get(f, f))
-@@ -2614,7 +3068,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2614,7 +3106,7 @@ class YumBase(depsolve.Depsolve):
          # ...but without showdups we want to output _just_ #3, which requires
          # we find the newest EVR po for the best "matching value". Without keys
          # it's the same, except we just want the newest EVR.
@@ -187595,7 +187691,7 @@ index 99039e0..d1ab41a 100644
          # either, so it's pretty thankless. HTH. HAND.
          # By default just sort using package sorting
          sort_func = operator.itemgetter(0)
-@@ -2661,6 +3115,14 @@ class YumBase(depsolve.Depsolve):
+@@ -2661,6 +3153,14 @@ class YumBase(depsolve.Depsolve):
                      yield (po, vs)
  
      def searchPackageTags(self, criteria):
@@ -187610,7 +187706,7 @@ index 99039e0..d1ab41a 100644
          results = {} # name = [(criteria, taglist)]
          for c in criteria:
              c = c.lower()
-@@ -2677,11 +3139,16 @@ class YumBase(depsolve.Depsolve):
+@@ -2677,11 +3177,16 @@ class YumBase(depsolve.Depsolve):
          return results
          
      def searchPackages(self, fields, criteria, callback=None):
@@ -187632,7 +187728,7 @@ index 99039e0..d1ab41a 100644
          warnings.warn(_('searchPackages() will go away in a future version of Yum.\
                        Use searchGenerator() instead. \n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)           
-@@ -2700,13 +3167,23 @@ class YumBase(depsolve.Depsolve):
+@@ -2700,13 +3205,23 @@ class YumBase(depsolve.Depsolve):
      
      def searchPackageProvides(self, args, callback=None,
                                callback_has_matchfor=False):
@@ -187660,7 +187756,7 @@ index 99039e0..d1ab41a 100644
              else:
                  isglob = True
                  canBeFile = misc.re_filename(arg)
-@@ -2723,7 +3200,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2723,7 +3238,7 @@ class YumBase(depsolve.Depsolve):
                  where = self.returnPackagesByDep(arg)
              else:
                  usedDepString = False
@@ -187669,7 +187765,7 @@ index 99039e0..d1ab41a 100644
              self.verbose_logger.log(logginglevels.DEBUG_1,
                 P_('Searching %d package', 'Searching %d packages', len(where)), len(where))
              
-@@ -2817,25 +3294,160 @@ class YumBase(depsolve.Depsolve):
+@@ -2817,25 +3332,160 @@ class YumBase(depsolve.Depsolve):
              
          return matches
  
@@ -187842,7 +187938,7 @@ index 99039e0..d1ab41a 100644
                  if uservisible:
                      if grp.user_visible:
                          installed.append(grp)
-@@ -2847,34 +3459,98 @@ class YumBase(depsolve.Depsolve):
+@@ -2847,34 +3497,98 @@ class YumBase(depsolve.Depsolve):
                          available.append(grp)
                  else:
                      available.append(grp)
@@ -187919,6 +188015,8 @@ index 99039e0..d1ab41a 100644
              thisgroup.toremove = True
 -            pkgs = thisgroup.packages
 -            for pkg in thisgroup.packages:
+-                txmbrs = self.remove(name=pkg, silence_warnings=True)
+-                txmbrs_used.extend(txmbrs)
 +
 +            if self.conf.group_command == 'objects':
 +                pkgs = thisgroup.pkg_names
@@ -187931,8 +188029,8 @@ index 99039e0..d1ab41a 100644
 +                if pkg in igroup_data and igroup_data[pkg] != 'installed':
 +                    continue
 +
-                 txmbrs = self.remove(name=pkg, silence_warnings=True)
-                 txmbrs_used.extend(txmbrs)
++                txmbrs = self.remove(name=pkg, silence_warnings=True)
++                txmbrs_used.extend(txmbrs)
                  for txmbr in txmbrs:
 -                    txmbr.groups.append(thisgroup.groupid)
 +                    txmbr.groups.append(gid)
@@ -187951,7 +188049,7 @@ index 99039e0..d1ab41a 100644
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -2898,13 +3574,58 @@ class YumBase(depsolve.Depsolve):
+@@ -2898,13 +3612,58 @@ class YumBase(depsolve.Depsolve):
                              self.tsInfo.remove(txmbr.po.pkgtup)
          
          
@@ -188017,7 +188115,7 @@ index 99039e0..d1ab41a 100644
          """
  
          if not self.comps.has_group(grpid):
-@@ -2920,6 +3641,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2920,6 +3679,9 @@ class YumBase(depsolve.Depsolve):
          if group_package_types:
              package_types = group_package_types
  
@@ -188027,7 +188125,7 @@ index 99039e0..d1ab41a 100644
          for thisgroup in thesegroups:
              if thisgroup.selected:
                  continue
-@@ -2934,12 +3658,51 @@ class YumBase(depsolve.Depsolve):
+@@ -2934,12 +3696,51 @@ class YumBase(depsolve.Depsolve):
              if 'optional' in package_types:
                  pkgs.extend(thisgroup.optional_packages)
  
@@ -188080,7 +188178,7 @@ index 99039e0..d1ab41a 100644
                  except Errors.InstallError, e:
                      self.verbose_logger.debug(_('No package named %s available to be installed'),
                          pkg)
-@@ -2953,7 +3716,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2953,7 +3754,9 @@ class YumBase(depsolve.Depsolve):
                  group_conditionals = enable_group_conditionals
  
              count_cond_test = 0
@@ -188091,7 +188189,7 @@ index 99039e0..d1ab41a 100644
                  for condreq, cond in thisgroup.conditional_packages.iteritems():
                      if self.isPackageInstalled(cond):
                          try:
-@@ -2990,17 +3755,23 @@ class YumBase(depsolve.Depsolve):
+@@ -2990,17 +3793,23 @@ class YumBase(depsolve.Depsolve):
                          if cond not in self.tsInfo.conditionals:
                              self.tsInfo.conditionals[cond] = []
                          self.tsInfo.conditionals[cond].extend(pkgs)
@@ -188122,7 +188220,7 @@ index 99039e0..d1ab41a 100644
          
          if not self.comps.has_group(grpid):
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3008,7 +3779,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3008,7 +3817,8 @@ class YumBase(depsolve.Depsolve):
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
@@ -188132,7 +188230,7 @@ index 99039e0..d1ab41a 100644
          for thisgroup in thesegroups:
              thisgroup.selected = False
              
-@@ -3034,13 +3806,102 @@ class YumBase(depsolve.Depsolve):
+@@ -3034,13 +3844,102 @@ class YumBase(depsolve.Depsolve):
                          for pkg in self.tsInfo.conditionals.get(txmbr.name, []):
                              self.tsInfo.remove(pkg.pkgtup)
          
@@ -188241,7 +188339,7 @@ index 99039e0..d1ab41a 100644
          # look it up in the self.localPackages first:
          for po in self.localPackages:
              if po.pkgtup == pkgtup:
-@@ -3049,7 +3910,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3049,7 +3948,7 @@ class YumBase(depsolve.Depsolve):
          pkgs = self.pkgSack.searchPkgTuple(pkgtup)
  
          if len(pkgs) == 0:
@@ -188250,7 +188348,7 @@ index 99039e0..d1ab41a 100644
              if allow_missing: #  This can happen due to excludes after .up has
                  return None   # happened.
              raise Errors.DepError, _('Package tuple %s could not be found in packagesack') % str(pkgtup)
-@@ -3065,13 +3926,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3065,13 +3964,21 @@ class YumBase(depsolve.Depsolve):
          return result
  
      def getInstalledPackageObject(self, pkgtup):
@@ -188277,7 +188375,7 @@ index 99039e0..d1ab41a 100644
              raise Errors.RpmDBError, _('Package tuple %s could not be found in rpmdb') % str(pkgtup)
  
          # Dito. FIXME from getPackageObject() for len() > 1 ... :)
-@@ -3079,9 +3948,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3079,9 +3986,11 @@ class YumBase(depsolve.Depsolve):
          return po
          
      def gpgKeyCheck(self):
@@ -188291,7 +188389,7 @@ index 99039e0..d1ab41a 100644
          gpgkeyschecked = self.conf.cachedir + '/.gpgkeyschecked.yum'
          if os.path.exists(gpgkeyschecked):
              return 1
-@@ -3106,9 +3977,13 @@ class YumBase(depsolve.Depsolve):
+@@ -3106,9 +4015,13 @@ class YumBase(depsolve.Depsolve):
              return 1
  
      def returnPackagesByDep(self, depstring):
@@ -188307,7 +188405,7 @@ index 99039e0..d1ab41a 100644
          if not depstring:
              return []
  
-@@ -3135,9 +4010,16 @@ class YumBase(depsolve.Depsolve):
+@@ -3135,9 +4048,16 @@ class YumBase(depsolve.Depsolve):
          return self.pkgSack.getProvides(depname, depflags, depver).keys()
  
      def returnPackageByDep(self, depstring):
@@ -188327,7 +188425,7 @@ index 99039e0..d1ab41a 100644
          # we get all sorts of randomness here
          errstring = depstring
          if type(depstring) not in types.StringTypes:
-@@ -3149,16 +4031,22 @@ class YumBase(depsolve.Depsolve):
+@@ -3149,16 +4069,22 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _('No Package found for %s') % errstring
          
          ps = ListPackageSack(pkglist)
@@ -188354,7 +188452,7 @@ index 99039e0..d1ab41a 100644
          if not depstring:
              return []
  
-@@ -3184,12 +4072,47 @@ class YumBase(depsolve.Depsolve):
+@@ -3184,12 +4110,47 @@ class YumBase(depsolve.Depsolve):
  
          return self.rpmdb.getProvides(depname, depflags, depver).keys()
  
@@ -188404,7 +188502,7 @@ index 99039e0..d1ab41a 100644
          
          
          if len(pkglist) == 0:
-@@ -3198,14 +4121,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3198,14 +4159,23 @@ class YumBase(depsolve.Depsolve):
          if len(pkglist) == 1:
              return pkglist[0]
  
@@ -188434,7 +188532,7 @@ index 99039e0..d1ab41a 100644
          returnlist = []
          compatArchList = self.arch.get_arch_list(arch)
          multiLib = []
-@@ -3222,9 +4154,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3222,9 +4192,9 @@ class YumBase(depsolve.Depsolve):
                  singleLib.append(po)
                  
          # we now have three lists.  find the best package(s) of each
@@ -188447,7 +188545,7 @@ index 99039e0..d1ab41a 100644
  
          if single_name and multi and single and multi.name != single.name:
              # Sinlge _must_ match multi, if we want a single package name
-@@ -3238,7 +4170,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3238,7 +4208,7 @@ class YumBase(depsolve.Depsolve):
          # if there's a noarch and it's newer than the multilib, we want
          # just the noarch.  otherwise, we want multi + single
          elif multi:
@@ -188456,7 +188554,7 @@ index 99039e0..d1ab41a 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3246,7 +4178,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3246,7 +4216,7 @@ class YumBase(depsolve.Depsolve):
                  if single: returnlist.append(single)
          # similar for the non-multilib case
          elif single:
@@ -188465,7 +188563,7 @@ index 99039e0..d1ab41a 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3350,28 +4282,58 @@ class YumBase(depsolve.Depsolve):
+@@ -3350,28 +4320,58 @@ class YumBase(depsolve.Depsolve):
              done = True
  
              slow = next_func(slow)
@@ -188529,7 +188627,7 @@ index 99039e0..d1ab41a 100644
          try:
              txmbrs = self.groupRemove(group_string)
          except yum.Errors.GroupsError:
-@@ -3387,6 +4349,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3387,6 +4387,8 @@ class YumBase(depsolve.Depsolve):
          assert pattern[0] == '@'
          grpid = pattern[1:]
  
@@ -188538,7 +188636,7 @@ index 99039e0..d1ab41a 100644
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3398,7 +4362,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3398,7 +4400,11 @@ class YumBase(depsolve.Depsolve):
      def _minus_deselect(self, pattern):
          """ Remove things from the transaction, like kickstart. """
          assert pattern[0] == '-'
@@ -188551,7 +188649,7 @@ index 99039e0..d1ab41a 100644
  
          if pat and pat[0] == '@':
              pat = pat[1:]
-@@ -3437,14 +4405,87 @@ class YumBase(depsolve.Depsolve):
+@@ -3437,14 +4443,87 @@ class YumBase(depsolve.Depsolve):
              if flag not in self.tsInfo.probFilterFlags:
                  self.tsInfo.probFilterFlags.append(flag)
  
@@ -188645,7 +188743,7 @@ index 99039e0..d1ab41a 100644
          pkgs = []
          was_pattern = False
          if po:
-@@ -3464,9 +4505,14 @@ class YumBase(depsolve.Depsolve):
+@@ -3464,9 +4543,14 @@ class YumBase(depsolve.Depsolve):
                  if kwargs['pattern'] and kwargs['pattern'][0] == '@':
                      return self._at_groupinstall(kwargs['pattern'])
  
@@ -188660,7 +188758,7 @@ index 99039e0..d1ab41a 100644
                                                        ignore_case=False)
                  pkgs.extend(mypkgs)
                  # if we have anything left unmatched, let's take a look for it
-@@ -3477,20 +4523,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3477,20 +4561,12 @@ class YumBase(depsolve.Depsolve):
                      self.verbose_logger.debug(_('Checking for virtual provide or file-provide for %s'), 
                          arg)
  
@@ -188687,7 +188785,7 @@ index 99039e0..d1ab41a 100644
              else:
                  nevra_dict = self._nevra_kwarg_parse(kwargs)
  
-@@ -3499,6 +4537,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3499,6 +4575,8 @@ class YumBase(depsolve.Depsolve):
                       ver=nevra_dict['version'], rel=nevra_dict['release'])
                  self._add_not_found_a(pkgs, nevra_dict)
                  
@@ -188696,7 +188794,7 @@ index 99039e0..d1ab41a 100644
              if pkgs:
                  # if was_pattern or nevra-dict['arch'] is none, take the list
                  # of arches based on our multilib_compat config and 
-@@ -3577,17 +4617,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3577,17 +4655,21 @@ class YumBase(depsolve.Depsolve):
                      continue
              
              # make sure this shouldn't be passed to update:
@@ -188722,7 +188820,7 @@ index 99039e0..d1ab41a 100644
                  obsoleting_pkg = self._test_loop(po, self._pkg2obspkg)
              if obsoleting_pkg is not None:
                  # this is not a definitive check but it'll make sure we don't
-@@ -3600,23 +4644,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3600,23 +4682,23 @@ class YumBase(depsolve.Depsolve):
                      already_obs = pkgs[0]
  
                  if already_obs:
@@ -188753,7 +188851,7 @@ index 99039e0..d1ab41a 100644
                      continue
  
              # make sure we don't have a name.arch of this already installed
-@@ -3630,8 +4674,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3630,8 +4712,8 @@ class YumBase(depsolve.Depsolve):
                          found = True
                          break
                  if not found:
@@ -188764,7 +188862,7 @@ index 99039e0..d1ab41a 100644
                      tx_return.extend(txmbrs)
                      continue
  
-@@ -3719,19 +4763,47 @@ class YumBase(depsolve.Depsolve):
+@@ -3719,19 +4801,47 @@ class YumBase(depsolve.Depsolve):
          return txmbr
  
      def update(self, po=None, requiringPo=None, update_to=False, **kwargs):
@@ -188819,7 +188917,7 @@ index 99039e0..d1ab41a 100644
          tx_return = []
          if not po and not kwargs: # update everything (the easy case)
              self.verbose_logger.log(logginglevels.DEBUG_2, _('Updating Everything'))
-@@ -3765,7 +4837,14 @@ class YumBase(depsolve.Depsolve):
+@@ -3765,7 +4875,14 @@ class YumBase(depsolve.Depsolve):
                      if new is None:
                          continue
                      tx_return.extend(self.update(po=new))
@@ -188835,7 +188933,7 @@ index 99039e0..d1ab41a 100644
              return tx_return
  
          # complications
-@@ -3787,13 +4866,16 @@ class YumBase(depsolve.Depsolve):
+@@ -3787,13 +4904,16 @@ class YumBase(depsolve.Depsolve):
                  return self._minus_deselect(kwargs['pattern'])
  
              if kwargs['pattern'] and kwargs['pattern'][0] == '@':
@@ -188854,7 +188952,7 @@ index 99039e0..d1ab41a 100644
  
              if not instpkgs and not availpkgs:
                  depmatches = []
-@@ -3805,6 +4887,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3805,6 +4925,8 @@ class YumBase(depsolve.Depsolve):
                  except yum.Errors.YumBaseError, e:
                      self.logger.critical(_('%s') % e)
  
@@ -188863,7 +188961,7 @@ index 99039e0..d1ab41a 100644
                  if update_to:
                      availpkgs.extend(depmatches)
                  else:
-@@ -3816,9 +4900,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3816,9 +4938,12 @@ class YumBase(depsolve.Depsolve):
              try:
                  if update_to:
                      m = []
@@ -188877,7 +188975,7 @@ index 99039e0..d1ab41a 100644
                      m = self.pkgSack.returnNewestByNameArch(patterns=pats)
              except Errors.PackageSackError:
                  m = []
-@@ -3843,7 +4930,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3843,7 +4968,7 @@ class YumBase(depsolve.Depsolve):
                      availpkgs = self._compare_providers(availpkgs, requiringPo)
                      availpkgs = map(lambda x: x[0], availpkgs)
                  elif not availpkgs:
@@ -188886,7 +188984,7 @@ index 99039e0..d1ab41a 100644
         
          # for any thing specified
          # get the list of available pkgs matching it (or take the po)
-@@ -3879,6 +4966,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3879,6 +5004,7 @@ class YumBase(depsolve.Depsolve):
                      if obsoleting_pkg is None:
                          continue
                      obs_pkgs.append(obsoleting_pkg)
@@ -188894,7 +188992,7 @@ index 99039e0..d1ab41a 100644
                  for obsoleting_pkg in packagesNewestByName(obs_pkgs):
                      tx_return.extend(self.install(po=obsoleting_pkg))
              for available_pkg in availpkgs:
-@@ -3920,11 +5008,29 @@ class YumBase(depsolve.Depsolve):
+@@ -3920,11 +5046,29 @@ class YumBase(depsolve.Depsolve):
                      tx_return.append(txmbr)
                          
          for available_pkg in availpkgs:
@@ -188924,7 +189022,7 @@ index 99039e0..d1ab41a 100644
                  self.verbose_logger.log(logginglevels.DEBUG_2, _('Not Updating Package that is obsoleted: %s'), available_pkg)
                  tx_return.extend(self.update(po=obsoleting_pkg))
                  continue
-@@ -3985,11 +5091,18 @@ class YumBase(depsolve.Depsolve):
+@@ -3985,11 +5129,18 @@ class YumBase(depsolve.Depsolve):
          return tx_return
          
      def remove(self, po=None, **kwargs):
@@ -188948,7 +189046,7 @@ index 99039e0..d1ab41a 100644
          if not po and not kwargs:
              raise Errors.RemoveError, 'Nothing specified to remove'
          
-@@ -4008,6 +5121,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4008,6 +5159,10 @@ class YumBase(depsolve.Depsolve):
                      return self._at_groupremove(kwargs['pattern'])
  
                  (e,m,u) = self.rpmdb.matchPackageNames([kwargs['pattern']])
@@ -188959,7 +189057,7 @@ index 99039e0..d1ab41a 100644
                  pkgs.extend(e)
                  pkgs.extend(m)
                  if u:
-@@ -4018,6 +5135,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4018,6 +5173,10 @@ class YumBase(depsolve.Depsolve):
                      except yum.Errors.YumBaseError, e:
                          self.logger.critical(_('%s') % e)
                      
@@ -188970,7 +189068,7 @@ index 99039e0..d1ab41a 100644
                      if not depmatches:
                          arg = to_unicode(arg)
                          self.logger.critical(_('No Match for argument: %s') % to_unicode(arg))
-@@ -4055,17 +5176,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4055,17 +5214,19 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def installLocal(self, pkg, po=None, updateonly=False):
@@ -189000,7 +189098,7 @@ index 99039e0..d1ab41a 100644
          # read in the package into a YumLocalPackage Object
          # append it to self.localPackages
          # check if it can be installed or updated based on nevra versus rpmdb
-@@ -4183,16 +5306,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4183,16 +5344,15 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def reinstallLocal(self, pkg, po=None):
@@ -189025,7 +189123,7 @@ index 99039e0..d1ab41a 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4215,13 +5337,29 @@ class YumBase(depsolve.Depsolve):
+@@ -4215,13 +5375,29 @@ class YumBase(depsolve.Depsolve):
          return self.reinstall(po=po)
  
      def reinstall(self, po=None, **kwargs):
@@ -189058,7 +189156,7 @@ index 99039e0..d1ab41a 100644
          tx_mbrs = []
          if po: # The po, is the "available" po ... we want the installed po
              tx_mbrs.extend(self.remove(pkgtup=po.pkgtup))
-@@ -4240,10 +5378,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4240,10 +5416,11 @@ class YumBase(depsolve.Depsolve):
              # pkgs that are obsolete.
              old_conf_obs = self.conf.obsoletes
              self.conf.obsoletes = False
@@ -189072,7 +189170,7 @@ index 99039e0..d1ab41a 100644
              self.conf.obsoletes = old_conf_obs
              if len(members) == 0:
                  self.tsInfo.remove(item.pkgtup)
-@@ -4259,16 +5398,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4259,16 +5436,15 @@ class YumBase(depsolve.Depsolve):
          return tx_mbrs
          
      def downgradeLocal(self, pkg, po=None):
@@ -189097,7 +189195,7 @@ index 99039e0..d1ab41a 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4309,13 +5447,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4309,13 +5485,19 @@ class YumBase(depsolve.Depsolve):
          return False
          
      def downgrade(self, po=None, **kwargs):
@@ -189124,7 +189222,7 @@ index 99039e0..d1ab41a 100644
          if not po and not kwargs:
              raise Errors.DowngradeError, 'Nothing specified to downgrade'
  
-@@ -4397,6 +5541,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4397,6 +5579,10 @@ class YumBase(depsolve.Depsolve):
          # installed version. Indexed fromn the latest installed pkgtup.
          downgrade_apkgs = {}
          for pkg in sorted(apkgs):
@@ -189135,7 +189233,7 @@ index 99039e0..d1ab41a 100644
              na  = (pkg.name, pkg.arch)
  
              # Here we allow downgrades from .i386 => .noarch, or .i586 => .i386
-@@ -4421,6 +5569,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4421,6 +5607,9 @@ class YumBase(depsolve.Depsolve):
                  warned_nas.add(na)
                  continue
  
@@ -189145,7 +189243,7 @@ index 99039e0..d1ab41a 100644
              if pkg.verGE(lipkg):
                  if na not in warned_nas:
                      msg = _('Only Upgrade available on package: %s') % pkg
-@@ -4457,7 +5608,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4457,7 +5646,7 @@ class YumBase(depsolve.Depsolve):
          if e and v and r:
              evr = '%s:%s-%s' % (e, v, r)
          elif v and r:
@@ -189154,7 +189252,7 @@ index 99039e0..d1ab41a 100644
          elif e and v:
              evr = '%s:%s' % (e, v)
          elif v: # e and r etc. is just too weird to print
-@@ -4500,12 +5651,24 @@ class YumBase(depsolve.Depsolve):
+@@ -4500,12 +5689,24 @@ class YumBase(depsolve.Depsolve):
  
          return returndict
  
@@ -189182,7 +189280,7 @@ index 99039e0..d1ab41a 100644
          old_conf_obs = self.conf.obsoletes
          self.conf.obsoletes = False
          done = False
-@@ -4515,19 +5678,46 @@ class YumBase(depsolve.Depsolve):
+@@ -4515,19 +5716,46 @@ class YumBase(depsolve.Depsolve):
                      done = True
          for pkg in transaction.trans_data:
              if pkg.state == 'Downgrade':
@@ -189229,7 +189327,7 @@ index 99039e0..d1ab41a 100644
                  if self.install(pkgtup=pkg.pkgtup):
                      done = True
          for pkg in transaction.trans_data:
-@@ -4538,8 +5728,14 @@ class YumBase(depsolve.Depsolve):
+@@ -4538,8 +5766,14 @@ class YumBase(depsolve.Depsolve):
          return done
  
      def history_undo(self, transaction):
@@ -189246,7 +189344,7 @@ index 99039e0..d1ab41a 100644
          # NOTE: This is somewhat basic atm. ... for instance we don't check
          #       that we are going from the old new version. However it's still
          #       better than the RHN rollback code, and people pay for that :).
-@@ -4616,7 +5812,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4616,7 +5850,7 @@ class YumBase(depsolve.Depsolve):
  
          except urlgrabber.grabber.URLGrabError, e:
              raise Errors.YumBaseError(_('GPG key retrieval failed: ') +
@@ -189255,7 +189353,7 @@ index 99039e0..d1ab41a 100644
                                        
          # check for a .asc file accompanying it - that's our gpg sig on the key
          # suck it down and do the check
-@@ -4649,7 +5845,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4649,7 +5883,7 @@ class YumBase(depsolve.Depsolve):
              keys_info = misc.getgpgkeyinfo(rawkey, multiple=True)
          except ValueError, e:
              raise Errors.YumBaseError(_('Invalid GPG Key from %s: %s') % 
@@ -189264,7 +189362,7 @@ index 99039e0..d1ab41a 100644
          keys = []
          for keyinfo in keys_info:
              thiskey = {}
-@@ -4674,39 +5870,49 @@ class YumBase(depsolve.Depsolve):
+@@ -4674,39 +5908,49 @@ class YumBase(depsolve.Depsolve):
              if pkgs:
                  pkgs = sorted(pkgs)[-1]
                  msg = (_('Importing %s key 0x%s:\n'
@@ -189332,7 +189430,7 @@ index 99039e0..d1ab41a 100644
          user_cb_fail = False
          for keyurl in keyurls:
              keys = self._retrievePublicKey(keyurl, repo)
-@@ -4725,7 +5931,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4725,7 +5969,9 @@ class YumBase(depsolve.Depsolve):
                      # Try installing/updating GPG key
                      self._getKeyImportMessage(info, keyurl)
                      rc = False
@@ -189343,7 +189441,7 @@ index 99039e0..d1ab41a 100644
                          rc = True
                          
                      # grab the .sig/.asc for the keyurl, if it exists
-@@ -4751,8 +5959,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4751,8 +5997,8 @@ class YumBase(depsolve.Depsolve):
                  ts = self.rpmdb.readOnlyTS()
                  result = ts.pgpImportPubkey(misc.procgpgkey(info['raw_key']))
                  if result != 0:
@@ -189354,7 +189452,7 @@ index 99039e0..d1ab41a 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
  
-@@ -4760,18 +5968,20 @@ class YumBase(depsolve.Depsolve):
+@@ -4760,18 +6006,20 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _("Didn't install any keys")
  
          if not key_installed:
@@ -189380,7 +189478,7 @@ index 99039e0..d1ab41a 100644
      
      def _getAnyKeyForRepo(self, repo, destdir, keyurl_list, is_cakey=False, callback=None):
          """
-@@ -4788,6 +5998,18 @@ class YumBase(depsolve.Depsolve):
+@@ -4788,6 +6036,18 @@ class YumBase(depsolve.Depsolve):
          """
  
          key_installed = False
@@ -189399,7 +189497,7 @@ index 99039e0..d1ab41a 100644
          user_cb_fail = False
          for keyurl in keyurl_list:
              keys = self._retrievePublicKey(keyurl, repo, getSig=not is_cakey)
-@@ -4819,8 +6041,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4819,8 +6079,11 @@ class YumBase(depsolve.Depsolve):
                  if not key_installed:
                      self._getKeyImportMessage(info, keyurl, keytype)
                      rc = False
@@ -189412,7 +189510,7 @@ index 99039e0..d1ab41a 100644
                      elif callback:
                          rc = callback({"repo": repo, "userid": info['userid'],
                                          "hexkeyid": info['hexkeyid'], "keyurl": keyurl,
-@@ -4835,7 +6060,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4835,7 +6098,8 @@ class YumBase(depsolve.Depsolve):
                  # Import the key
                  result = misc.import_key_to_pubring(info['raw_key'], info['hexkeyid'], gpgdir=destdir)
                  if not result:
@@ -189422,7 +189520,7 @@ index 99039e0..d1ab41a 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
                  # write out the key id to imported_cakeys in the repos basedir
-@@ -4851,36 +6077,35 @@ class YumBase(depsolve.Depsolve):
+@@ -4851,36 +6115,35 @@ class YumBase(depsolve.Depsolve):
                              pass
  
          if not key_installed and user_cb_fail:
@@ -189475,7 +189573,7 @@ index 99039e0..d1ab41a 100644
          self._getAnyKeyForRepo(repo, repo.gpgcadir, repo.gpgcakey, is_cakey=True, callback=callback)
  
      def _limit_installonly_pkgs(self):
-@@ -4889,7 +6114,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4889,7 +6152,7 @@ class YumBase(depsolve.Depsolve):
              New in 3.2.24: Obey yumdb_info.installonly data. """
  
          def _sort_and_filter_installonly(pkgs):
@@ -189484,7 +189582,7 @@ index 99039e0..d1ab41a 100644
                  using the yumdb. """
              ret_beg = []
              ret_mid = []
-@@ -4926,23 +6151,30 @@ class YumBase(depsolve.Depsolve):
+@@ -4926,23 +6189,30 @@ class YumBase(depsolve.Depsolve):
          # so self.rpmdb.ts should be valid.
          ts = self.rpmdb.readOnlyTS()
          (cur_kernel_v, cur_kernel_r) = misc.get_running_kernel_version_release(ts)
@@ -189523,7 +189621,7 @@ index 99039e0..d1ab41a 100644
              for po in installed:
                  if (po.version, po.release) == (cur_kernel_v, cur_kernel_r): 
                      # don't remove running
-@@ -4959,19 +6191,22 @@ class YumBase(depsolve.Depsolve):
+@@ -4959,19 +6229,22 @@ class YumBase(depsolve.Depsolve):
              txmbr.depends_on.append(rel)
  
      def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None):
@@ -189559,7 +189657,7 @@ index 99039e0..d1ab41a 100644
          
          if not callback:
              callback = callbacks.ProcessTransNoOutputCallback()
-@@ -5062,8 +6297,8 @@ class YumBase(depsolve.Depsolve):
+@@ -5062,8 +6335,8 @@ class YumBase(depsolve.Depsolve):
                  raise Errors.YumRPMCheckError, retmsgs
              retmsgs = [_('ERROR with transaction check vs depsolve:')]
              retmsgs.extend(msgs) 
@@ -189570,7 +189668,7 @@ index 99039e0..d1ab41a 100644
              raise Errors.YumRPMCheckError,retmsgs
          
          tsConf = {}
-@@ -5114,13 +6349,19 @@ class YumBase(depsolve.Depsolve):
+@@ -5114,13 +6387,19 @@ class YumBase(depsolve.Depsolve):
          return results
  
      def add_enable_repo(self, repoid, baseurls=[], mirrorlist=None, **kwargs):
@@ -189597,7 +189695,7 @@ index 99039e0..d1ab41a 100644
          # out of place fixme - maybe we should make this the default repo addition
          # routine and use it from getReposFromConfigFile(), etc.
          newrepo = yumRepo.YumRepository(repoid)
-@@ -5167,9 +6408,15 @@ class YumBase(depsolve.Depsolve):
+@@ -5167,9 +6446,15 @@ class YumBase(depsolve.Depsolve):
  
      def setCacheDir(self, force=False, tmpdir=None, reuse=True,
                      suffix='/$basearch/$releasever'):
@@ -189616,7 +189714,7 @@ index 99039e0..d1ab41a 100644
          if not force and os.geteuid() == 0:
              return True # We are root, not forced, so happy with the global dir.
          if tmpdir is None:
-@@ -5179,7 +6426,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5179,7 +6464,7 @@ class YumBase(depsolve.Depsolve):
          try:
              cachedir = misc.getCacheDir(tmpdir, reuse)
          except (IOError, OSError), e:
@@ -189625,7 +189723,7 @@ index 99039e0..d1ab41a 100644
              cachedir = None
              
          if cachedir is None:
-@@ -5190,6 +6437,8 @@ class YumBase(depsolve.Depsolve):
+@@ -5190,6 +6475,8 @@ class YumBase(depsolve.Depsolve):
              self.prerepoconf.cachedir = cachedir
          else:
              self.repos.setCacheDir(cachedir)
@@ -189634,7 +189732,7 @@ index 99039e0..d1ab41a 100644
          self.conf.cachedir = cachedir
          return True # We got a new cache dir
  
-@@ -5220,13 +6469,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5220,13 +6507,24 @@ class YumBase(depsolve.Depsolve):
          self.history.write_addon_data('config-repos', myrepos)
          
      def verify_plugins_cb(self, verify_package):
@@ -189662,7 +189760,7 @@ index 99039e0..d1ab41a 100644
          if self.tsInfo._unresolvedMembers:
              if auto:
                  self.logger.critical(_("Dependencies not solved. Will not save unresolved transaction."))
-@@ -5234,7 +6494,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5234,7 +6532,7 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError(_("Dependencies not solved. Will not save unresolved transaction."))
          
          if not filename:
@@ -189671,7 +189769,7 @@ index 99039e0..d1ab41a 100644
              fd,filename = tempfile.mkstemp(suffix='.yumtx', prefix=prefix)
              f = os.fdopen(fd, 'w')
          else:
-@@ -5244,13 +6504,17 @@ class YumBase(depsolve.Depsolve):
+@@ -5244,13 +6542,17 @@ class YumBase(depsolve.Depsolve):
          
          msg = "%s\n" % self.rpmdb.simpleVersion(main_only=True)[0]
          msg += "%s\n" % self.ts.getTsFlags()
@@ -189692,7 +189790,7 @@ index 99039e0..d1ab41a 100644
          msg += "%s\n" % len(self.tsInfo.getMembers())
          for txmbr in self.tsInfo.getMembers():
              msg += txmbr._dump()
-@@ -5260,42 +6524,84 @@ class YumBase(depsolve.Depsolve):
+@@ -5260,42 +6562,84 @@ class YumBase(depsolve.Depsolve):
          except (IOError, OSError), e:
              self._ts_save_file = None
              if auto:
@@ -189789,7 +189887,7 @@ index 99039e0..d1ab41a 100644
              if ignorerpm:
                  msg += _(" ignoring, as requested.")
                  self.logger.critical(_(msg))
-@@ -5318,8 +6624,17 @@ class YumBase(depsolve.Depsolve):
+@@ -5318,8 +6662,17 @@ class YumBase(depsolve.Depsolve):
          numrepos = int(data[2].strip())
          repos = []
          rindex=3+numrepos
@@ -189808,7 +189906,7 @@ index 99039e0..d1ab41a 100644
  
          # pkgs/txmbrs
          numpkgs = int(data[rindex].strip())
-@@ -5329,6 +6644,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5329,6 +6682,7 @@ class YumBase(depsolve.Depsolve):
          pkgcount = 0
          pkgprob = False
          curpkg = None
@@ -189816,7 +189914,7 @@ index 99039e0..d1ab41a 100644
          for l in data[pkgstart:]:
              l = l.rstrip()
              # our main txmbrs
-@@ -5356,6 +6672,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5356,6 +6710,7 @@ class YumBase(depsolve.Depsolve):
                      if not ignoremissing:
                          raise Errors.YumBaseError(msg)
                      else:
@@ -189824,7 +189922,7 @@ index 99039e0..d1ab41a 100644
                          self.logger.critical(msg)
                  else:
                      pkgcount += 1
-@@ -5432,12 +6749,18 @@ class YumBase(depsolve.Depsolve):
+@@ -5432,12 +6787,18 @@ class YumBase(depsolve.Depsolve):
          if pkgprob:
              msg = _("Transaction members, relations are missing or ts has been modified,")
              if ignoremissing:
@@ -189843,7 +189941,7 @@ index 99039e0..d1ab41a 100644
          return self.tsInfo.getMembers()
  
      def _remove_old_deps(self):
-@@ -5470,18 +6793,6 @@ class YumBase(depsolve.Depsolve):
+@@ -5470,18 +6831,6 @@ class YumBase(depsolve.Depsolve):
                      if requiring == required: # if they are self-requiring skip them
                          continue
                          
@@ -189862,7 +189960,7 @@ index 99039e0..d1ab41a 100644
                      #for tbi_pkg in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
                      #   for reqtuple in tbi_pkg.po.requires:
                      #        if required.provides_for(reqtuple):
-@@ -5533,7 +6844,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5533,7 +6882,24 @@ class YumBase(depsolve.Depsolve):
                      # Debugging output
                      self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has revdep %s which was user-installed."), pkg, curpkg)
                      ok_to_remove[pkg] = False
@@ -189887,7 +189985,7 @@ index 99039e0..d1ab41a 100644
                  visited[curpkg] = True
              all_leaves_visited = True
              leaves = curpkg.requiring_packages()
-@@ -5547,4 +6875,3 @@ class YumBase(depsolve.Depsolve):
+@@ -5547,4 +6913,3 @@ class YumBase(depsolve.Depsolve):
          # Debugging output
          self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has no user-installed revdeps."), pkg)
          return False
@@ -190495,7 +190593,7 @@ index 65f6d5e..fe5649d 100755
          print >> sys.stderr, "newcomps.py: No such file:\'%s\'" % sys.argv[1]
          sys.exit(1)
 diff --git a/yum/config.py b/yum/config.py
-index d09511f..438cb88 100644
+index d09511f..ec7ba80 100644
 --- a/yum/config.py
 +++ b/yum/config.py
 @@ -45,15 +45,18 @@ from misc import get_uuid, read_in_items_from_dot_dir
@@ -191190,14 +191288,15 @@ index d09511f..438cb88 100644
  
      cachedir = Option('/var/cache/yum')
  
-@@ -641,20 +734,23 @@ class YumConf(StartupConf):
+@@ -641,20 +734,24 @@ class YumConf(StartupConf):
  
      commands = ListOption()
      exclude = ListOption()
 -    failovermethod = Option('roundrobin')
 -    proxy = UrlOption(schemes=('http', 'ftp', 'https'), allow_none=True)
 +    failovermethod = Option(__main_failovermethod_default__)
-+    proxy = UrlOption(default=False, schemes=('http', 'ftp', 'https'), allow_none=True)
++    proxy = UrlOption(default=False, schemes=('http', 'ftp', 'https',
++        'socks4', 'socks4a', 'socks5', 'socks5h'), allow_none=True)
      proxy_username = Option()
      proxy_password = Option()
      username = Option()
@@ -191217,7 +191316,7 @@ index d09511f..438cb88 100644
                                            names_of_0=["0", "<off>"])
      kernelpkgnames = ListOption(['kernel','kernel-smp', 'kernel-enterprise',
              'kernel-bigmem', 'kernel-BOOT', 'kernel-PAE', 'kernel-PAE-debug'])
-@@ -664,6 +760,7 @@ class YumConf(StartupConf):
+@@ -664,6 +761,7 @@ class YumConf(StartupConf):
      tsflags = ListOption()
  
      assumeyes = BoolOption(False)
@@ -191225,7 +191324,7 @@ index d09511f..438cb88 100644
      alwaysprompt = BoolOption(True)
      exactarch = BoolOption(True)
      tolerant = BoolOption(True)
-@@ -677,18 +774,32 @@ class YumConf(StartupConf):
+@@ -677,18 +775,32 @@ class YumConf(StartupConf):
      obsoletes = BoolOption(True)
      showdupesfromrepos = BoolOption(False)
      enabled = BoolOption(True)
@@ -191258,7 +191357,7 @@ index d09511f..438cb88 100644
      # Time in seconds (1 day). NOTE: This isn't used when using metalinks
      mirrorlist_expire = SecondsOption(60 * 60 * 24)
      # XXX rpm_check_debug is unused, left around for API compatibility for now
-@@ -698,12 +809,14 @@ class YumConf(StartupConf):
+@@ -698,12 +810,14 @@ class YumConf(StartupConf):
      #  Note that "instant" is the old behaviour, but group:primary is very
      # similar but better :).
      mdpolicy = ListOption(['group:primary'])
@@ -191275,7 +191374,7 @@ index d09511f..438cb88 100644
  
      color = SelectionOption('auto', ('auto', 'never', 'always'),
                              mapper={'on' : 'always', 'yes' : 'always',
-@@ -715,22 +828,27 @@ class YumConf(StartupConf):
+@@ -715,22 +829,27 @@ class YumConf(StartupConf):
      color_list_installed_newer = Option('bold,yellow')
      color_list_installed_reinstall = Option('normal')
      color_list_installed_extra = Option('bold,red')
@@ -191303,7 +191402,7 @@ index d09511f..438cb88 100644
  
      history_record = BoolOption(True)
      history_record_packages = ListOption(['yum', 'rpm'])
-@@ -744,18 +862,29 @@ class YumConf(StartupConf):
+@@ -744,18 +863,29 @@ class YumConf(StartupConf):
      
      loadts_ignoremissing = BoolOption(False)
      loadts_ignorerpm = BoolOption(False)
@@ -191333,7 +191432,7 @@ index d09511f..438cb88 100644
          output = '[main]\n'
          # we exclude all vars which start with _ or are in this list:
          excluded_vars = ('cfg', 'uid', 'yumvar', 'progress_obj', 'failure_obj',
-@@ -778,14 +907,12 @@ class YumConf(StartupConf):
+@@ -778,14 +908,12 @@ class YumConf(StartupConf):
          return output
  
  class RepoConf(BaseConfig):
@@ -191351,7 +191450,7 @@ index d09511f..438cb88 100644
          ck = self.__cached_keys
          if not isinstance(self, RepoConf):
              ck = set()
-@@ -823,39 +950,48 @@ class RepoConf(BaseConfig):
+@@ -823,39 +951,48 @@ class RepoConf(BaseConfig):
      bandwidth = Inherit(YumConf.bandwidth)
      throttle = Inherit(YumConf.throttle)
      timeout = Inherit(YumConf.timeout)
@@ -191411,7 +191510,7 @@ index d09511f..438cb88 100644
  
      # ' xemacs syntax hack
  
-@@ -876,20 +1012,24 @@ def readStartupConfig(configfile, root):
+@@ -876,20 +1013,24 @@ def readStartupConfig(configfile, root):
              raise Errors.ConfigError("All plugin search paths must be absolute")
      # Stuff this here to avoid later re-parsing
      startupconf._parser = parser
@@ -191442,7 +191541,7 @@ index d09511f..438cb88 100644
      
      # ' xemacs syntax hack
  
-@@ -956,6 +1096,12 @@ def readMainConfig(startupconf):
+@@ -956,6 +1097,12 @@ def readMainConfig(startupconf):
      return yumconf
  
  def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
@@ -191455,7 +191554,7 @@ index d09511f..438cb88 100644
      parser = ConfigParser()
      confpp_obj = ConfigPreProcessor(configfile)
      try:
-@@ -970,17 +1116,16 @@ def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
+@@ -970,17 +1117,16 @@ def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
  
  
  def getOption(conf, section, name, option):
@@ -191483,7 +191582,7 @@ index d09511f..438cb88 100644
      try: 
          val = conf.get(section, name)
      except (NoSectionError, NoOptionError):
-@@ -1028,25 +1173,28 @@ def _getsysver(installroot, distroverpkg):
+@@ -1028,25 +1174,28 @@ def _getsysver(installroot, distroverpkg):
      if idx.count() == 0:
          releasever = '$releasever'
      else:
@@ -191523,7 +191622,7 @@ index d09511f..438cb88 100644
      # b/c repoids can have $values in them we need to map both ways to figure
      # out which one is which
      section_id = repo.id
-@@ -1054,6 +1202,19 @@ def writeRawRepoFile(repo,only=None):
+@@ -1054,6 +1203,19 @@ def writeRawRepoFile(repo,only=None):
          for sect in ini._sections.keys():
              if varReplace(sect, repo.yumvar) == repo.id:
                  section_id = sect
@@ -191543,7 +191642,7 @@ index d09511f..438cb88 100644
      
      # Updated the ConfigParser with the changed values    
      cfgOptions = repo.cfg.options(repo.id)
-@@ -1069,7 +1230,7 @@ def writeRawRepoFile(repo,only=None):
+@@ -1069,7 +1231,7 @@ def writeRawRepoFile(repo,only=None):
          #  If the value is the same, but just interpreted ... when we don't want
          # to keep the interpreted values.
          if (name in ini[section_id] and
@@ -195925,6 +196024,527 @@ index 2cb1acb..3ac0010 100644
  
      def __unicode__(self):
          ret = u''
+diff --git a/yum/updateinfo.py b/yum/updateinfo.py
+new file mode 100644
+index 0000000..7d37a76
+--- /dev/null
++++ b/yum/updateinfo.py
+@@ -0,0 +1,515 @@
++
++import os.path
++
++from yum.i18n import _, P_
++
++from yum.constants import *
++
++from yum.logginglevels import INFO_1
++
++import rpmUtils.miscutils
++
++import misc
++
++import fnmatch
++
++# newpackages is weird, in that we'll never display that because we filter to
++# things relevant to installed pkgs...
++_update_info_types_ = ("security", "bugfix", "enhancement",
++                       "recommended", "newpackage")
++
++def _rpm_tup_vercmp(tup1, tup2):
++    """ Compare two "std." tuples, (n, a, e, v, r). """
++    return rpmUtils.miscutils.compareEVR((tup1[2], tup1[3], tup1[4]),
++                                         (tup2[2], tup2[3], tup2[4]))
++
++
++def _ysp_safe_refs(refs):
++    """ Sometimes refs == None, if so return the empty list here. 
++        So we don't have to check everywhere. """
++    if not refs:
++        return []
++    return refs
++
++def _match_sec_cmd(sec_cmds, pkgname, notice):
++    for i in sec_cmds:
++        if fnmatch.fnmatch(pkgname, i):
++            return i
++        if notice['update_id'] == i:
++            return i
++    return None
++
++def _has_id(used_map, refs, ref_type, ref_ids):
++    ''' Check if the given ID is a match. '''
++    for ref in _ysp_safe_refs(refs):
++        if ref['type'] != ref_type:
++            continue
++        if ref['id'] not in ref_ids:
++            continue
++        used_map[ref_type][ref['id']] = True
++        return ref
++    return None
++    
++def _ysp_should_filter_pkg(opts, pkgname, notice, used_map):
++    """ Do the package filtering for should_show and should_keep. """
++    
++    rcmd = _match_sec_cmd(opts.sec_cmds, pkgname, notice)
++    if rcmd:
++        used_map['cmd'][rcmd] = True
++        return True
++    elif opts.advisory and notice['update_id'] in opts.advisory:
++        used_map['id'][notice['update_id']] = True
++        return True
++    elif (opts.severity and notice['type'] == 'security' and
++          notice['severity'] in opts.severity):
++        used_map['sev'][notice['severity']] = True
++        return True
++    elif opts.cve and _has_id(used_map, notice['references'], "cve", opts.cve):
++        return True
++    elif opts.bz and _has_id(used_map, notice['references'],"bugzilla",opts.bz):
++        return True
++    # FIXME: Add opts for enhancement/etc.? -- __update_info_types__
++    elif (opts.security and notice['type'] == 'security' and
++          (not opts.severity or 'severity' not in notice or
++           not notice['severity'])):
++        return True
++    elif opts.bugfixes and notice['type'] == 'bugfix':
++        return True
++    elif not (opts.advisory or opts.cve or opts.bz or
++              opts.security or opts.bugfixes or opts.sec_cmds or opts.severity):
++        return True # This is only possible from should_show_pkg
++
++    return False
++
++def _ysp_has_info_md(rname, md):
++    if rname in _update_info_types_:
++        if md['type'] == rname:
++            return md
++    for ref in _ysp_safe_refs(md['references']):
++        if ref['type'] != rname:
++            continue
++        return md
++
++def _no_options(opts):
++    return not (opts.security or opts.bugfixes or
++                opts.advisory or opts.bz or opts.cve or opts.severity)
++
++def _updateinfofilter2opts(updateinfo_filters):
++    opts = misc.GenericHolder()
++    opts.sec_cmds = []
++
++    opts.advisory = updateinfo_filters.get('advs', [])
++    opts.bz       = updateinfo_filters.get('bzs',  [])
++    opts.cve      = updateinfo_filters.get('cves', [])
++    opts.severity = updateinfo_filters.get('sevs', [])
++
++    opts.bugfixes = updateinfo_filters.get('bugfix', False)
++    opts.security = updateinfo_filters.get('security', False)
++
++    return opts
++
++def _args2filters(args):
++    # Basically allow args to turn into security filters, for shell command etc.
++
++    T_map = {'advs' : 'advs',
++             'advisory' : 'advs',
++             'advisories' : 'advs',
++
++             'bzs' : 'bzs',
++             'bz' : 'bzs',
++
++             'cves' : 'cves',
++             'cve' : 'cves',
++
++             'security-severity' : 'sevs',
++             'security-severities' : 'sevs',
++             'severity' : 'sevs',
++             'severities' : 'sevs',
++             'sevs' : 'sevs',
++             'sev' : 'sevs',
++
++             'security' : 'security',
++             'sec' : 'security',
++
++             'bugfix' : 'bugfix',
++             'bugfixes' : 'bugfix',
++             'bugs' : 'bugfix',
++
++             }
++
++    filters = {'security' : False, 'bugfix' : False}
++
++    for arg0 in args:
++        arg0 = arg0.replace(" ", ',')
++        T = 'advs'
++        if '=' in arg0:
++            T, arg1 = arg0.split('=', 1)
++        elif arg0 not in T_map:
++            arg1 = arg0
++        else:
++            T = arg0
++            arg1 = 'true'
++
++        if T not in T_map:
++            continue # Error message?
++
++        T = T_map[T]
++
++        if T in ('security', 'bugfix'):
++            filters[T] = not filters[T]
++        else:
++            filters[T] = filters.get(T, []) + arg1.split(',')
++        return filters
++
++def _ysp_gen_used_map(opts):
++    used_map = {'bugzilla' : {}, 'cve' : {}, 'id' : {}, 'cmd' : {}, 'sev' : {}}
++    if True:
++        return used_map
++    for i in opts.sec_cmds:
++        used_map['cmd'][i] = False
++    for i in opts.advisory:
++        used_map['id'][i] = False
++    for i in opts.bz:
++        used_map['bugzilla'][i] = False
++    for i in opts.cve:
++        used_map['cve'][i] = False
++    for i in opts.severity:
++        used_map['sev'][i] = False
++    return used_map
++
++def _ysp_chk_used_map(used_map, msg):
++    for i in used_map['cmd']:
++        if not used_map['cmd'][i]:
++            msg('No update information found for \"%s\"' % i)
++    for i in used_map['id']:
++        if not used_map['id'][i]:
++            msg('Advisory \"%s\" not found applicable for this system' % i)
++    for i in used_map['bugzilla']:
++        if not used_map['bugzilla'][i]:
++            msg('BZ \"%s\" not found applicable for this system' % i)
++    for i in used_map['cve']:
++        if not used_map['cve'][i]:
++            msg('CVE \"%s\" not found applicable for this system' % i)
++    for i in used_map['sev']:
++        if not used_map['sev'][i]:
++            msg('Severity \"%s\" not found applicable for this system' % i)
++
++
++def _get_name2pkgtup(base, pkgtups):
++    name2tup = {}
++    for pkgtup in pkgtups:
++        # Get the latest "old" pkgtups
++        if (pkgtup[0] in name2tup and
++            _rpm_tup_vercmp(name2tup[pkgtup[0]], pkgtup) > 0):
++            continue
++        name2tup[pkgtup[0]] = pkgtup
++    return name2tup
++def _get_name2oldpkgtup(base):
++    """ Get the pkgtups for all installed pkgs. which have an update. """
++    oupdates = map(lambda x: x[1], base.up.getUpdatesTuples())
++    return _get_name2pkgtup(base, oupdates)
++def _get_name2instpkgtup(base):
++    """ Get the pkgtups for all installed pkgs. """
++    return _get_name2pkgtup(base, base.rpmdb.simplePkgList())
++def _get_name2allpkgtup(base):
++    """ Get the pkgtups for all installed pkgs. and munge that to be the
++        first possible pkgtup. """
++    ofirst = [(pt[0], pt[1], '0','0','0') for pt in base.rpmdb.simplePkgList()]
++    return _get_name2pkgtup(base, ofirst)
++def _get_name2aallpkgtup(base):
++    """ Get the pkgtups for all available pkgs. and munge that to be the
++        first possible pkgtup. """
++    ofirst = [(pt[0], pt[1],'0','0','0') for pt in base.pkgSack.simplePkgList()]
++    return _get_name2pkgtup(base, ofirst)
++
++
++#  You might think we'd just call delPackage
++# and indeed that works for list updates etc.
++#
++# __but__ that doesn't work for dependancies on real updates
++#
++#  So to fix deps. we need to do it at the preresolve stage and take the
++# "transaction package list" and then remove packages from that.
++#
++# __but__ that doesn't work for lists ... so we do it two ways
++#
++def _ysp_should_keep_pkg(opts, pkgtup, md_info, used_map):
++    """ Do we want to keep this package to satisfy the security limits. """
++    name = pkgtup[0]
++    for (pkgtup, notice) in md_info.get_applicable_notices(pkgtup):
++        if _ysp_should_filter_pkg(opts, name, notice, used_map):
++            return True
++    return False
++
++def _repos_downloaded(repos):
++    dled = True
++    for repo in repos:
++        try:
++            data = repo.repoXML.getData('updateinfo');
++        except:
++            continue # No data is fine...
++
++        # Note that this doesn't check that it's decompressed...
++        path = repo.cachedir +'/'+ os.path.basename(data.location[1])
++        if not os.path.exists(path):
++            dled = False
++            break
++
++    return dled
++
++def _check_running_kernel(yb, md_info, msg):
++    kern_pkgtup = misc.get_running_kernel_pkgtup(yb.ts)
++    if kern_pkgtup[0] is None:
++        return
++
++    found_sec = False
++    for (pkgtup, notice) in md_info.get_applicable_notices(kern_pkgtup):
++        if found_sec or notice['type'] != 'security':
++            continue
++        found_sec = True
++        ipkg = yb.rpmdb.searchPkgTuple(pkgtup)
++        if not ipkg:
++            continue # Not installed
++        ipkg = ipkg[0]
++
++        e = ''
++        if kern_pkgtup[2] != '0':
++            e = '%s:' % kern_pkgtup[2]
++        rpkg = '%s-%s%s-%s.%s' % (kern_pkgtup[0], e,
++                                  kern_pkgtup[3], kern_pkgtup[4],
++                                  kern_pkgtup[1])
++
++        msg(_('Security: %s is an installed security update') % ipkg)
++        msg(_('Security: %s is the currently running version') % rpkg)
++        break
++
++def remove_txmbrs(base, filters=None):
++    '''
++    Remove packages from the transaction, using the updateinfo data.
++    '''
++    md_info = base.upinfo
++
++    def ysp_del_pkg(tspkg):
++        """ Deletes a package within a transaction. """
++        base.verbose_logger.log(INFO_1,
++                                _(" --> %s from %s removed (updateinfo)") %
++                                (tspkg.po, tspkg.po.ui_from_repo))
++        tsinfo.remove(tspkg.pkgtup)
++
++    if filters is None:
++        filters = base.updateinfo_filters
++    opts = _updateinfofilter2opts(filters)
++
++    if _no_options(opts):
++        return 0, 0, 0
++
++    tot = 0
++    cnt = 0
++    used_map = _ysp_gen_used_map(opts)
++    tsinfo = base.tsInfo
++    tspkgs = tsinfo.getMembers()
++    #  Ok, here we keep any pkgs that pass "ysp" tests, then we keep all
++    # related pkgs ... Ie. "installed" version marked for removal.
++    keep_pkgs = set()
++
++    count_states = set(TS_INSTALL_STATES + [TS_ERASE])
++    count_pkgs = set()
++    for tspkg in tspkgs:
++        if tspkg.output_state in count_states:
++            count_pkgs.add(tspkg.po)
++
++    name2tup = _get_name2oldpkgtup(base)
++    for tspkg in tspkgs:
++        if tspkg.output_state in count_states:
++            tot += 1
++        name = tspkg.po.name
++        if (name not in name2tup or
++            not _ysp_should_keep_pkg(opts, name2tup[name], md_info, used_map)):
++            continue
++        if tspkg.output_state in count_states:
++            cnt += 1
++        keep_pkgs.add(tspkg.po)
++
++    scnt = cnt
++    mini_depsolve_again = True
++    while mini_depsolve_again:
++        mini_depsolve_again = False
++
++        for tspkg in tspkgs:
++            if tspkg.po in keep_pkgs:
++                # Find any related pkgs, and add them:
++                for (rpkg, reason) in tspkg.relatedto:
++                    if rpkg not in keep_pkgs:
++                        if rpkg in count_pkgs:
++                            cnt += 1
++                        keep_pkgs.add(rpkg)
++                        mini_depsolve_again = True
++            else:
++                # If related to any keep pkgs, add us
++                for (rpkg, reason) in tspkg.relatedto:
++                    if rpkg in keep_pkgs:
++                        if rpkg in count_pkgs:
++                            cnt += 1
++                        keep_pkgs.add(tspkg.po)
++                        mini_depsolve_again = True
++                        break
++
++    for tspkg in tspkgs:
++        if tspkg.po not in keep_pkgs:
++            ysp_del_pkg(tspkg)
++
++    _ysp_chk_used_map(used_map, lambda x: base.verbose_logger.warn("%s", x))
++    
++    if cnt:
++        base.verbose_logger.log(INFO_1, _('%d package(s) needed (+%d related) for security, out of %d available') % (scnt, cnt - scnt, tot))
++    else:
++        base.verbose_logger.log(INFO_1, _('No packages needed for security; %d packages available') % tot)
++
++    return cnt, scnt, tot
++
++def exclude_updates(base, filters=None):
++    '''
++    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,
++                                _(" --> %s from %s excluded (%s)") %
++                                (pkg,pkg.repoid, reason))
++        pkg.repo.sack.delPackage(pkg)
++
++    if filters is None:
++        filters = base.updateinfo_filters
++    opts = _updateinfofilter2opts(filters)
++
++    if _no_options(opts):
++        return 0, 0
++
++    used_map = _ysp_gen_used_map(opts)
++
++    # In theory the official API is:
++    #
++    # pkgs = base.pkgSack.returnPackages()
++    #
++    # ...however that is _extremely_ slow, deleting all packages. So we ask
++    # for the list of update packages, which is all we care about.    
++    upds = base.doPackageLists(pkgnarrow='updates')
++    pkgs = upds.updates
++    # In theory we don't need to do this in some cases, but meh.
++    upds = base.doPackageLists(pkgnarrow='obsoletes')
++    pkgs += upds.obsoletes
++
++    name2tup = _get_name2oldpkgtup(base)
++    
++    tot = 0
++    cnt = 0
++    for pkg in pkgs:
++        tot += 1
++        name = pkg.name
++        if (name not in name2tup or
++            not _ysp_should_keep_pkg(opts, name2tup[name], md_info, used_map)):
++            ysp_del_pkg(pkg)
++            continue
++        cnt += 1
++
++    _ysp_chk_used_map(used_map, lambda x: base.verbose_logger.warn("%s", x))
++
++    if cnt:
++        base.verbose_logger.log(INFO_1, _('%d package(s) needed for security, out of %d available') % (cnt, tot))
++    else:
++        base.verbose_logger.log(INFO_1, _('No packages needed for security; %d packages available' % tot))
++
++    return cnt, tot
++
++def exclude_all(base, filters=None):
++    '''
++    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,
++                                _(" --> %s from %s excluded (%s)") %
++                                (pkg,pkg.repoid, reason))
++        pkg.repo.sack.delPackage(pkg)
++
++    if filters is None:
++        filters = base.updateinfo_filters
++    opts = _updateinfofilter2opts(filters)
++
++    if _no_options(opts):
++        return 0, 0
++
++    used_map = _ysp_gen_used_map(opts)
++
++    pkgs = base.pkgSack.returnPackages()
++    name2tup = _get_name2aallpkgtup(base)
++    
++    tot = 0
++    cnt = 0
++    for pkg in pkgs:
++        tot += 1
++        name = pkg.name
++        if (name not in name2tup or
++            not _ysp_should_keep_pkg(opts, name2tup[name], md_info, used_map)):
++            ysp_del_pkg(pkg)
++            continue
++        cnt += 1
++
++    _ysp_chk_used_map(used_map, lambda x: base.verbose_logger.warn("%s", x))
++
++    if cnt:
++        base.verbose_logger.log(INFO_1, _('%d package(s) needed for security, out of %d available') % (cnt, tot))
++    else:
++        base.verbose_logger.log(INFO_1, _('No packages needed for security; %d packages available' % tot))
++
++    return cnt, tot
++
++def update_minimal(base, extcmds=[]):
++    """Mark the specified items to be updated, in the minimal way.
++    :param extcmds: the user specified arguments
++    :return: a list of transaction members added to the
++       transaction set by this function
++    """
++    txmbrs = []
++
++    used_map = _ysp_gen_used_map(base.updateinfo_filters)
++    opts     = _updateinfofilter2opts(base.updateinfo_filters)
++    ndata    = _no_options(opts)
++
++    # NOTE: Not doing obsoletes processing atm. ... maybe we should? --
++    # Also worth pointing out we don't go backwards for obsoletes in the:
++    # update --security case etc.
++
++    # obsoletes = base.up.getObsoletesTuples(newest=False)
++    # for (obsoleting, installed) in sorted(obsoletes, key=lambda x: x[0]):
++    #   pass
++
++    # Tuples == (n, a, e, v, r)
++    oupdates  = map(lambda x: x[1], base.up.getUpdatesTuples())
++    for oldpkgtup in sorted(oupdates):
++        data = base.upinfo.get_applicable_notices(oldpkgtup)
++        if ndata: # No options means pick the oldest update
++            data.reverse()
++
++        for (pkgtup, notice) in data:
++            name = pkgtup[0]
++            if extcmds and not _match_sec_cmd(extcmds, name, notice):
++                continue
++            if (not ndata and
++                not _ysp_should_filter_pkg(base, name, notice, used_map)):
++                continue
++            txmbrs.extend(base.update(name=pkgtup[0], arch=pkgtup[1],
++                                      epoch=pkgtup[2],
++                                      version=pkgtup[3], release=pkgtup[4]))
++            break
++
++    # _ysp_chk_used_map(used_map, msg)
++
++    return txmbrs
++
 diff --git a/yum/yumRepo.py b/yum/yumRepo.py
 index e5e9ece..2e4fcd9 100644
 --- a/yum/yumRepo.py
@@ -196953,10 +197573,18 @@ index e5e9ece..2e4fcd9 100644
          fo = None
  
 diff --git a/yumcommands.py b/yumcommands.py
-index 4dcbea7..968f231 100644
+index 4dcbea7..e5f2363 100644
 --- a/yumcommands.py
 +++ b/yumcommands.py
-@@ -22,14 +22,16 @@ Classes for subcommands of the yum command line interface.
+@@ -13,6 +13,7 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ # Copyright 2006 Duke University 
++# Copyright 2013 Red Hat
+ # Written by Seth Vidal
+ 
+ """
+@@ -22,16 +23,19 @@ Classes for subcommands of the yum command line interface.
  import os
  import cli
  from yum import logginglevels
@@ -196974,8 +197602,11 @@ index 4dcbea7..968f231 100644
 +import glob
  
  import yum.config
++from yum import updateinfo
  
-@@ -43,16 +45,24 @@ def _err_mini_usage(base, basecmd):
+ def _err_mini_usage(base, basecmd):
+     if basecmd not in base.yum_cli_commands:
+@@ -43,16 +47,24 @@ def _err_mini_usage(base, basecmd):
      base.logger.critical(txt)
  
  def checkRootUID(base):
@@ -197003,7 +197634,7 @@ index 4dcbea7..968f231 100644
      if not base.gpgKeyCheck():
          for repo in base.repos.listEnabled():
              if (repo.gpgcheck or repo.repo_gpgcheck) and not repo.gpgkey:
-@@ -75,31 +85,118 @@ For more information contact your distribution or package provider.
+@@ -75,31 +87,118 @@ For more information contact your distribution or package provider.
                  raise cli.CliError
  
  def checkPackageArg(base, basecmd, extcmds):
@@ -197122,7 +197753,7 @@ index 4dcbea7..968f231 100644
  
      for cmd in extcmds:
          if cmd not in VALID_ARGS:
-@@ -108,12 +205,14 @@ def checkCleanArg(base, basecmd, extcmds):
+@@ -108,12 +207,14 @@ def checkCleanArg(base, basecmd, extcmds):
              raise cli.CliError
  
  def checkShellArg(base, basecmd, extcmds):
@@ -197143,7 +197774,7 @@ index 4dcbea7..968f231 100644
      """
      if len(extcmds) == 0:
          base.verbose_logger.debug(_("No argument to shell"))
-@@ -133,10 +232,12 @@ def checkShellArg(base, basecmd, extcmds):
+@@ -133,10 +234,12 @@ def checkShellArg(base, basecmd, extcmds):
          raise cli.CliError
  
  def checkEnabledRepo(base, possible_local_files=[]):
@@ -197159,7 +197790,7 @@ index 4dcbea7..968f231 100644
      """
      if base.repos.listEnabled():
          return
-@@ -152,113 +253,301 @@ def checkEnabledRepo(base, possible_local_files=[]):
+@@ -152,113 +255,305 @@ def checkEnabledRepo(base, possible_local_files=[]):
      raise cli.CliError
  
  class YumCommand:
@@ -197408,7 +198039,10 @@ index 4dcbea7..968f231 100644
 +        """
          self.doneCommand(base, _("Setting up Update Process"))
          try:
-             return base.updatePkgs(extcmds, update_to=(basecmd == 'update-to'))
+-            return base.updatePkgs(extcmds, update_to=(basecmd == 'update-to'))
++            ret = base.updatePkgs(extcmds, update_to=(basecmd == 'update-to'))
++            updateinfo.remove_txmbrs(base)
++            return ret
          except yum.Errors.YumBaseError, e:
 -            return 1, [str(e)]
 +            return 1, [exception2msg(e)]
@@ -197470,14 +198104,17 @@ index 4dcbea7..968f231 100644
          self.doneCommand(base, _("Setting up Distribution Synchronization Process"))
          try:
              base.conf.obsoletes = 1
-             return base.distroSyncPkgs(extcmds)
+-            return base.distroSyncPkgs(extcmds)
++            ret = base.distroSyncPkgs(extcmds)
++            updateinfo.remove_txmbrs(base)
++            return ret
          except yum.Errors.YumBaseError, e:
 -            return 1, [str(e)]
 +            return 1, [exception2msg(e)]
  
  def _add_pkg_simple_list_lens(data, pkg, indent=''):
      """ Get the length of each pkg's column. Add that to data.
-@@ -289,21 +578,57 @@ def _list_cmd_calc_columns(base, ypl):
+@@ -289,21 +584,63 @@ def _list_cmd_calc_columns(base, ypl):
      return (-columns[0], -columns[1], -columns[2])
  
  class InfoCommand(YumCommand):
@@ -197523,6 +198160,12 @@ index 4dcbea7..968f231 100644
 +            1 = we've errored, exit with error string
 +            2 = we've got work yet to do, onto the next stage
 +        """
++
++        if extcmds and extcmds[0] in ('updates', 'obsoletes'):
++            updateinfo.exclude_updates(base)
++        else:
++            updateinfo.exclude_all(base)
++
          try:
              highlight = base.term.MODE['bold']
 -            ypl = base.returnPkgLists(extcmds, installed_available=highlight)
@@ -197539,7 +198182,7 @@ index 4dcbea7..968f231 100644
          else:
              update_pkgs = {}
              inst_pkgs   = {}
-@@ -341,6 +666,7 @@ class InfoCommand(YumCommand):
+@@ -341,6 +678,7 @@ class InfoCommand(YumCommand):
                          local_pkgs[(po.name, po.arch)] = po
  
              # Output the packages:
@@ -197547,7 +198190,7 @@ index 4dcbea7..968f231 100644
              clio = base.conf.color_list_installed_older
              clin = base.conf.color_list_installed_newer
              clir = base.conf.color_list_installed_reinstall
-@@ -348,7 +674,9 @@ class InfoCommand(YumCommand):
+@@ -348,7 +686,9 @@ class InfoCommand(YumCommand):
              rip = base.listPkgs(ypl.installed, _('Installed Packages'), basecmd,
                                  highlight_na=update_pkgs, columns=columns,
                                  highlight_modes={'>' : clio, '<' : clin,
@@ -197557,7 +198200,7 @@ index 4dcbea7..968f231 100644
              clau = base.conf.color_list_available_upgrade
              clad = base.conf.color_list_available_downgrade
              clar = base.conf.color_list_available_reinstall
-@@ -356,6 +684,7 @@ class InfoCommand(YumCommand):
+@@ -356,6 +696,7 @@ class InfoCommand(YumCommand):
              rap = base.listPkgs(ypl.available, _('Available Packages'), basecmd,
                                  highlight_na=inst_pkgs, columns=columns,
                                  highlight_modes={'<' : clau, '>' : clad,
@@ -197565,7 +198208,7 @@ index 4dcbea7..968f231 100644
                                                   '=' : clar, 'not in' : clai})
              rep = base.listPkgs(ypl.extras, _('Extra Packages'), basecmd,
                                  columns=columns)
-@@ -374,7 +703,7 @@ class InfoCommand(YumCommand):
+@@ -374,7 +715,7 @@ class InfoCommand(YumCommand):
                  for obtup in sorted(ypl.obsoletesTuples,
                                      key=operator.itemgetter(0)):
                      base.updatesObsoletesList(obtup, 'obsoletes',
@@ -197574,7 +198217,7 @@ index 4dcbea7..968f231 100644
              else:
                  rop = base.listPkgs(ypl.obsoletes, _('Obsoleting Packages'),
                                      basecmd, columns=columns)
-@@ -389,45 +718,163 @@ class InfoCommand(YumCommand):
+@@ -389,45 +730,163 @@ class InfoCommand(YumCommand):
              return 0, []
  
      def needTs(self, base, basecmd, extcmds):
@@ -197741,7 +198384,7 @@ index 4dcbea7..968f231 100644
          return True
  
   
-@@ -442,12 +889,25 @@ class GroupsCommand(YumCommand):
+@@ -442,12 +901,25 @@ class GroupsCommand(YumCommand):
                         'groupinfo'    : 'info'}
  
      def getNames(self):
@@ -197767,7 +198410,7 @@ index 4dcbea7..968f231 100644
          return _("Display, or use, the groups information")
      
      def _grp_setup_doCommand(self, base):
-@@ -459,7 +919,7 @@ class GroupsCommand(YumCommand):
+@@ -459,7 +931,7 @@ class GroupsCommand(YumCommand):
          except yum.Errors.GroupsError:
              return 1, [_('No Groups on which to run command')]
          except yum.Errors.YumBaseError, e:
@@ -197776,7 +198419,7 @@ index 4dcbea7..968f231 100644
  
      def _grp_cmd(self, basecmd, extcmds):
          if basecmd in self.direct_commands:
-@@ -470,6 +930,10 @@ class GroupsCommand(YumCommand):
+@@ -470,6 +942,10 @@ class GroupsCommand(YumCommand):
          else:
              cmd = 'summary'
  
@@ -197787,7 +198430,7 @@ index 4dcbea7..968f231 100644
          remap = {'update' : 'upgrade',
                   'erase' : 'remove',
                   'mark-erase' : 'mark-remove',
-@@ -479,32 +943,76 @@ class GroupsCommand(YumCommand):
+@@ -479,32 +955,76 @@ class GroupsCommand(YumCommand):
          return cmd, extcmds
  
      def doCheck(self, base, basecmd, extcmds):
@@ -197874,7 +198517,14 @@ index 4dcbea7..968f231 100644
          cmd, extcmds = self._grp_cmd(basecmd, extcmds)
  
          self._grp_setup_doCommand(base)
-@@ -524,122 +1032,530 @@ class GroupsCommand(YumCommand):
+@@ -520,126 +1040,538 @@ class GroupsCommand(YumCommand):
+             if cmd == 'install':
+                 return base.installGroups(extcmds)
+             if cmd == 'upgrade':
+-                return base.installGroups(extcmds, upgrade=True)
++                ret = base.installGroups(extcmds, upgrade=True)
++                updateinfo.remove_txmbrs(base)
++                return ret
              if cmd == 'remove':
                  return base.removeGroups(extcmds)
  
@@ -198346,6 +198996,7 @@ index 4dcbea7..968f231 100644
 +        """
          base.logger.debug("Searching Packages: ")
          try:
++            updateinfo.exclude_updates(base)
              return base.provides(extcmds)
          except yum.Errors.YumBaseError, e:
 -            return 1, [str(e)]
@@ -198413,12 +199064,20 @@ index 4dcbea7..968f231 100644
 +            1 = we've errored, exit with error string
 +            2 = we've got work yet to do, onto the next stage
 +        """
++        updateinfo.exclude_updates(base)
          obscmds = ['obsoletes'] + extcmds
          base.extcmds.insert(0, 'updates')
          result = 0
-@@ -676,161 +1592,480 @@ class CheckUpdateCommand(YumCommand):
+@@ -675,162 +1607,492 @@ class CheckUpdateCommand(YumCommand):
+                     base.updatesObsoletesList(obtup, 'obsoletes',
                                                columns=columns)
                  result = 100
++
++            # Add check_running_kernel call, if updateinfo is available.
++            if updateinfo._repos_downloaded(base.repos.listEnabled()):
++                def _msg(x):
++                    base.verbose_logger.info("%s", x)
++                updateinfo._check_running_kernel(base, base.upinfo, _msg)
          except yum.Errors.YumBaseError, e:
 -            return 1, [str(e)]
 +            return 1, [exception2msg(e)]
@@ -198489,6 +199148,7 @@ index 4dcbea7..968f231 100644
 +        """
          base.logger.debug(_("Searching Packages: "))
          try:
++            updateinfo.exclude_updates(base)
              return base.search(extcmds)
          except yum.Errors.YumBaseError, e:
 -            return 1, [str(e)]
@@ -198573,7 +199233,10 @@ index 4dcbea7..968f231 100644
          base.conf.obsoletes = 1
          self.doneCommand(base, _("Setting up Upgrade Process"))
          try:
-             return base.updatePkgs(extcmds, update_to=(basecmd == 'upgrade-to'))
+-            return base.updatePkgs(extcmds, update_to=(basecmd == 'upgrade-to'))
++            ret = base.updatePkgs(extcmds, update_to=(basecmd == 'upgrade-to'))
++            updateinfo.remove_txmbrs(base)
++            return ret
          except yum.Errors.YumBaseError, e:
 -            return 1, [str(e)]
 +            return 1, [exception2msg(e)]
@@ -198705,6 +199368,7 @@ index 4dcbea7..968f231 100644
 +        """
          base.logger.debug(_("Searching Packages for Dependency:"))
          try:
++            updateinfo.exclude_updates(base)
              return base.resolveDepCli(extcmds)
          except yum.Errors.YumBaseError, e:
 -            return 1, [str(e)]
@@ -198845,6 +199509,7 @@ index 4dcbea7..968f231 100644
 +        """
          self.doneCommand(base, _("Finding dependencies: "))
          try:
++            updateinfo.exclude_updates(base)
              return base.deplist(extcmds)
          except yum.Errors.YumBaseError, e:
 -            return 1, [str(e)]
@@ -198906,7 +199571,7 @@ index 4dcbea7..968f231 100644
          def _repo_size(repo):
              ret = 0
              for pkg in repo.sack.returnPackages():
-@@ -857,7 +2092,10 @@ class RepoListCommand(YumCommand):
+@@ -857,7 +2119,10 @@ class RepoListCommand(YumCommand):
              arg = 'enabled'
          extcmds = map(lambda x: x.lower(), extcmds)
  
@@ -198918,7 +199583,7 @@ index 4dcbea7..968f231 100644
          if arg != 'disabled' or extcmds:
              try:
                  # Setup so len(repo.sack) is correct
-@@ -866,6 +2104,13 @@ class RepoListCommand(YumCommand):
+@@ -866,6 +2131,13 @@ class RepoListCommand(YumCommand):
              except yum.Errors.RepoError:
                  if verbose:
                      raise
@@ -198932,7 +199597,7 @@ index 4dcbea7..968f231 100644
  
          repos = base.repos.repos.values()
          repos.sort()
-@@ -924,111 +2169,108 @@ class RepoListCommand(YumCommand):
+@@ -924,111 +2196,108 @@ class RepoListCommand(YumCommand):
                  ui_enabled = dhibeg + _('disabled') + hiend
                  ui_endis_wid = utf8_width(_('disabled'))
  
@@ -199137,7 +199802,7 @@ index 4dcbea7..968f231 100644
  
          if not verbose and cols:
              #  Work out the first (id) and last (enabled/disalbed/count),
-@@ -1088,21 +2330,64 @@ class RepoListCommand(YumCommand):
+@@ -1088,21 +2357,64 @@ class RepoListCommand(YumCommand):
          return 0, ['repolist: ' +to_unicode(locale.format("%d", tot_num, True))]
  
      def needTs(self, base, basecmd, extcmds):
@@ -199202,7 +199867,7 @@ index 4dcbea7..968f231 100644
          if len(extcmds) == 0:
              base.usage()
              raise cli.CliError
-@@ -1147,28 +2432,85 @@ class HelpCommand(YumCommand):
+@@ -1147,28 +2459,85 @@ class HelpCommand(YumCommand):
          return help_output
  
      def doCommand(self, base, basecmd, extcmds):
@@ -199288,7 +199953,7 @@ index 4dcbea7..968f231 100644
          self.doneCommand(base, _("Setting up Reinstall Process"))
          try:
              return base.reinstallPkgs(extcmds)
-@@ -1177,49 +2519,139 @@ class ReInstallCommand(YumCommand):
+@@ -1177,49 +2546,139 @@ class ReInstallCommand(YumCommand):
              return 1, [to_unicode(e)]
  
      def getSummary(self):
@@ -199429,7 +200094,7 @@ index 4dcbea7..968f231 100644
          vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1308,7 +2740,7 @@ class VersionCommand(YumCommand):
+@@ -1308,7 +2767,7 @@ class VersionCommand(YumCommand):
                                       str(data[2][grp])))
                          _append_repos(cols, data[3][grp])
              except yum.Errors.YumBaseError, e:
@@ -199438,7 +200103,7 @@ index 4dcbea7..968f231 100644
          if vcmd in ('available', 'all', 'group-available', 'group-all'):
              try:
                  data = base.pkgSack.simpleVersion(not verbose, groups=groups)
-@@ -1327,7 +2759,7 @@ class VersionCommand(YumCommand):
+@@ -1327,7 +2786,7 @@ class VersionCommand(YumCommand):
                          if verbose:
                              _append_repos(cols, data[3][grp])
              except yum.Errors.YumBaseError, e:
@@ -199447,7 +200112,7 @@ index 4dcbea7..968f231 100644
  
          data = {'rid' : {}, 'ver' : {}}
          for (rid, ver) in cols:
-@@ -1344,6 +2776,14 @@ class VersionCommand(YumCommand):
+@@ -1344,6 +2803,14 @@ class VersionCommand(YumCommand):
          return 0, ['version']
  
      def needTs(self, base, basecmd, extcmds):
@@ -199462,7 +200127,7 @@ index 4dcbea7..968f231 100644
          vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1352,25 +2792,74 @@ class VersionCommand(YumCommand):
+@@ -1352,25 +2819,74 @@ class VersionCommand(YumCommand):
              return True
          return vcmd in ('available', 'all', 'group-available', 'group-all')
  
@@ -199538,7 +200203,7 @@ index 4dcbea7..968f231 100644
              return 2, ["Repeating transaction %u" % (old.tid,)]
  
      def _hcmd_undo(self, base, extcmds):
-@@ -1426,12 +2915,57 @@ class HistoryCommand(YumCommand):
+@@ -1426,12 +2942,57 @@ class HistoryCommand(YumCommand):
      def _hcmd_new(self, base, extcmds):
          base.history._create_db_file()
  
@@ -199597,7 +200262,7 @@ index 4dcbea7..968f231 100644
          if extcmds and extcmds[0] not in cmds:
              base.logger.critical(_('Invalid history sub-command, use: %s.'),
                                   ", ".join(cmds))
-@@ -1444,6 +2978,19 @@ class HistoryCommand(YumCommand):
+@@ -1444,6 +3005,19 @@ class HistoryCommand(YumCommand):
              raise cli.CliError
  
      def doCommand(self, base, basecmd, extcmds):
@@ -199617,7 +200282,7 @@ index 4dcbea7..968f231 100644
          vcmd = 'list'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1468,29 +3015,88 @@ class HistoryCommand(YumCommand):
+@@ -1468,29 +3042,88 @@ class HistoryCommand(YumCommand):
              ret = self._hcmd_rollback(base, extcmds)
          elif vcmd == 'new':
              ret = self._hcmd_new(base, extcmds)
@@ -199706,7 +200371,7 @@ index 4dcbea7..968f231 100644
          chkcmd = 'all'
          if extcmds:
              chkcmd = extcmds
-@@ -1505,24 +3111,147 @@ class CheckRpmdbCommand(YumCommand):
+@@ -1505,24 +3138,147 @@ class CheckRpmdbCommand(YumCommand):
          return rc, ['%s %s' % (basecmd, chkcmd)]
  
      def needTs(self, base, basecmd, extcmds):
@@ -199857,7 +200522,7 @@ index 4dcbea7..968f231 100644
          self.doneCommand(base, _("loading transaction from %s") % load_file)
          
          try:
-@@ -1533,5 +3262,417 @@ class LoadTransactionCommand(YumCommand):
+@@ -1533,5 +3289,809 @@ class LoadTransactionCommand(YumCommand):
  
  
      def needTs(self, base, basecmd, extcmds):
@@ -199872,8 +200537,8 @@ index 4dcbea7..968f231 100644
 +        if not extcmds or os.path.isdir(extcmds[0]):
 +            return False
 +
-+        return True
-+
+         return True
+ 
 +    def cacheRequirement(self, base, basecmd, extcmds):
 +        """Return the cache requirements for the remote repos.
 +
@@ -200088,6 +200753,7 @@ index 4dcbea7..968f231 100644
 +                num += len(txmbrs)
 +
 +            if num:
++                updateinfo.remove_txmbrs(base)
 +                return 2, P_('%d package to update', '%d packages to update',
 +                             num)
 +
@@ -200098,6 +200764,7 @@ index 4dcbea7..968f231 100644
 +                num += len(txmbrs)
 +
 +            if num:
++                updateinfo.remove_txmbrs(base)
 +                return 2, P_('%d package to update', '%d packages to update',
 +                             num)
 +
@@ -200259,8 +200926,8 @@ index 4dcbea7..968f231 100644
 +        if cmd in ('info', 'list'):
 +            return InfoCommand().cacheRequirement(base, cmd, extcmds[2:])
 +
-         return True
- 
++        return True
++
 +    def cacheRequirement(self, base, basecmd, extcmds):
 +        """Return the cache requirements for the remote repos.
 +
@@ -200275,6 +200942,396 @@ index 4dcbea7..968f231 100644
 +        if cmd in ('info', 'list'):
 +            return InfoCommand().cacheRequirement(base, cmd, extcmds[2:])
 +        return 'write'
++
++# Using this a lot, so make it easier...
++_upi = updateinfo
++class UpdateinfoCommand(YumCommand):
++    # Old command names...
++    direct_cmds = {'list-updateinfo'    : 'list',
++                   'list-security'      : 'list',
++                   'list-sec'           : 'list',
++                   'info-updateinfo'    : 'info',
++                   'info-security'      : 'info',
++                   'info-sec'           : 'info',
++                   'summary-updateinfo' : 'summary'}
++
++    #  Note that this code (instead of using inheritance and multiple
++    # cmd classes) means that "yum help" only displays the updateinfo command.
++    # Which is what we want, because the other commands are just backwards
++    # compatible gunk we don't want the user using).
++    def getNames(self):
++        return ['updateinfo'] + sorted(self.direct_cmds.keys())
++
++    def getUsage(self):
++        return "[info|list|...] [security|...] [installed|available|all] [pkgs|id]"
++
++    def getSummary(self):
++        return "Acts on repository update information"
++
++    def doCheck(self, base, basecmd, extcmds):
++        pass
++
++    def list_show_pkgs(self, base, md_info, list_type, show_type,
++                       iname2tup, data, msg):
++        n_maxsize = 0
++        r_maxsize = 0
++        t_maxsize = 0
++        for (notice, pkgtup, pkg) in data:
++            n_maxsize = max(len(notice['update_id']), n_maxsize)
++            tn = notice['type']
++            if tn == 'security' and notice['severity']:
++                tn = notice['severity'] + '/Sec.'
++            t_maxsize = max(len(tn),                  t_maxsize)
++            if show_type:
++                for ref in _upi._ysp_safe_refs(notice['references']):
++                    if ref['type'] != show_type:
++                        continue
++                    r_maxsize = max(len(str(ref['id'])), r_maxsize)
++
++        for (notice, pkgtup, pkg) in data:
++            mark = ''
++            if list_type == 'all':
++                mark = '  '
++                if _upi._rpm_tup_vercmp(iname2tup[pkgtup[0]], pkgtup) >= 0:
++                    mark = 'i '
++            tn = notice['type']
++            if tn == 'security' and notice['severity']:
++                tn = notice['severity'] + '/Sec.'
++
++            if show_type and _upi._ysp_has_info_md(show_type, notice):
++                for ref in _upi._ysp_safe_refs(notice['references']):
++                    if ref['type'] != show_type:
++                        continue
++                    msg("%s %-*s %-*s %s" % (mark, r_maxsize, str(ref['id']),
++                                             t_maxsize, tn, pkg))
++            elif hasattr(pkg, 'name'):
++                print base.fmtKeyValFill("%s: " % pkg.name,
++                                         base._enc(pkg.summary))
++            else:
++                msg("%s%-*s %-*s %s" % (mark, n_maxsize, notice['update_id'],
++                                        t_maxsize, tn, pkg))
++
++    def info_show_pkgs(self, base, md_info, list_type, show_type,
++                       iname2tup, data, msg):
++        show_pkg_info_done = {}
++        for (notice, pkgtup, pkg) in data:
++            if notice['update_id'] in show_pkg_info_done:
++                continue
++            show_pkg_info_done[notice['update_id']] = notice
++
++            if hasattr(notice, 'text'):
++                debug_log_lvl = yum.logginglevels.DEBUG_3
++                vlog = base.verbose_logger
++                if vlog.isEnabledFor(debug_log_lvl):
++                    obj = notice.text(skip_data=[])
++                else:
++                    obj = notice.text()
++            else:
++                # Python-2.4.* doesn't understand str(x) returning unicode
++                obj = notice.__str__()
++
++            if list_type == 'all':
++                if _upi._rpm_tup_vercmp(iname2tup[pkgtup[0]], pkgtup) >= 0:
++                    obj = obj + "\n  Installed : true"
++                else:
++                    obj = obj + "\n  Installed : false"
++            msg(obj)
++
++    def summary_show_pkgs(self, base, md_info, list_type, show_type,
++                          iname2tup, data, msg):
++        def _msg(x):
++            base.verbose_logger.info("%s", x)
++        counts = {}
++        sev_counts = {}
++        show_pkg_info_done = {}
++        for (notice, pkgtup, pkg) in data:
++            if notice['update_id'] in show_pkg_info_done:
++                continue
++            show_pkg_info_done[notice['update_id']] = notice
++            counts[notice['type']] = counts.get(notice['type'], 0) + 1
++            if notice['type'] == 'security':
++                sev = notice['severity']
++                if sev is None:
++                    sev = ''
++                sev_counts[sev] = sev_counts.get(sev, 0) + 1
++
++        maxsize = 0
++        for T in ('newpackage', 'security', 'bugfix', 'enhancement'):
++            if T not in counts:
++                continue
++            size = len(str(counts[T]))
++            if maxsize < size:
++                maxsize = size
++        if not maxsize:
++            _upi._check_running_kernel(base, md_info, _msg)
++            return
++
++        outT = {'newpackage' : 'New Package',
++                'security' : 'Security',
++                'bugfix' : 'Bugfix',
++                'enhancement' : 'Enhancement'}
++        print "Updates Information Summary:", list_type
++        for T in ('newpackage', 'security', 'bugfix', 'enhancement'):
++            if T not in counts:
++                continue
++            n = outT[T]
++            if T == 'security' and len(sev_counts) == 1:
++                sn = sev_counts.keys()[0]
++                if sn != '':
++                    n = sn + " " + n
++            print "    %*u %s notice(s)" % (maxsize, counts[T], n)
++            if T == 'security' and len(sev_counts) != 1:
++                def _sev_sort_key(key):
++                    # We want these in order, from "highest" to "lowest".
++                    # Anything unknown is "higher". meh.
++                    return {'Critical' : "zz1",
++                            'Important': "zz2",
++                            'Moderate' : "zz3",
++                            'Low'      : "zz4",
++                            }.get(key, key)
++
++                for sn in sorted(sev_counts, key=_sev_sort_key):
++                    args = (maxsize, sev_counts[sn],sn or '?', outT['security'])
++                    print "        %*u %s %s notice(s)" % args
++        _upi._check_running_kernel(base, md_info, _msg)
++        self.show_pkg_info_done = {}
++
++    def _get_new_pkgs(self, md_info):
++        for notice in md_info.notices:
++            if notice['type'] != "newpackage":
++                continue
++            for upkg in notice['pkglist']:
++                for pkg in upkg['packages']:
++                    pkgtup = (pkg['name'], pkg['arch'], pkg['epoch'] or '0',
++                              pkg['version'], pkg['release'])
++                    yield (notice, pkgtup)
++
++    _cmd2filt = {"bugzillas" : "bugzilla",
++                 "bugzilla" : "bugzilla",
++                 "bzs" : "bugzilla",
++                 "bz" : "bugzilla",
++
++                 "sec" : "security",
++
++                 "cves" : "cve",
++                 "cve" : "cve",
++
++                 "newpackages" : "newpackage",
++                 "new-packages" : "newpackage",
++                 "newpackage" : "newpackage",
++                 "new-package" : "newpackage",
++                 "new" : "newpackage"}
++    for filt_type in _upi._update_info_types_:
++        _cmd2filt[filt_type] = filt_type
++
++    def doCommand(self, base, basecmd, extcmds):
++        if basecmd in self.direct_cmds:
++            subcommand = self.direct_cmds[basecmd]
++        elif extcmds and extcmds[0] in ('list', 'info', 'summary',
++                                        'remove-pkgs-ts', 'exclude-updates',
++                                        'exclude-all',
++                                        'check-running-kernel'):
++            subcommand = extcmds[0]
++            extcmds = extcmds[1:]
++        elif extcmds and extcmds[0] in self._cmd2filt:
++            subcommand = 'list'
++        elif extcmds:
++            subcommand = 'info'
++        else:
++            subcommand = 'summary'
++
++        if subcommand == 'list':
++            return self.doCommand_li(base, 'updateinfo list', extcmds,
++                                     self.list_show_pkgs)
++        if subcommand == 'info':
++            return self.doCommand_li(base, 'updateinfo info', extcmds,
++                                     self.info_show_pkgs)
++
++        if subcommand == 'summary':
++            return self.doCommand_li(base, 'updateinfo summary', extcmds,
++                                     self.summary_show_pkgs)
++
++        if subcommand == 'remove-pkgs-ts':
++            filters = None
++            if extcmds:
++                filters = updateinfo._args2filters(extcmds)
++            updateinfo.remove_txmbrs(base, filters)
++            return 0, [basecmd + ' ' + subcommand + ' done']
++
++        if subcommand == 'exclude-all':
++            filters = None
++            if extcmds:
++                filters = updateinfo._args2filters(extcmds)
++            updateinfo.exclude_all(base, filters)
++            return 0, [basecmd + ' ' + subcommand + ' done']
++
++        if subcommand == 'exclude-updates':
++            filters = None
++            if extcmds:
++                filters = updateinfo._args2filters(extcmds)
++            updateinfo.exclude_updates(base, filters)
++            return 0, [basecmd + ' ' + subcommand + ' done']
++
++        if subcommand == 'check-running-kernel':
++            def _msg(x):
++                base.verbose_logger.info("%s", x)
++            updateinfo._check_running_kernel(base, base.upinfo, _msg)
++            return 0, [basecmd + ' ' + subcommand + ' done']
++
++    def doCommand_li_new(self, base, list_type, extcmds, md_info, msg,
++                         show_pkgs):
++        done_pkgs = set()
++        data = []
++        for (notice, pkgtup) in sorted(self._get_new_pkgs(md_info),
++                                       key=lambda x: x[1][0]):
++            if extcmds and not _upi._match_sec_cmd(extcmds, pkgtup[0], notice):
++                continue
++            n = pkgtup[0]
++            if n in done_pkgs:
++                continue
++            ipkgs = list(reversed(sorted(base.rpmdb.searchNames([n]))))
++            if list_type in ('installed', 'updates') and not ipkgs:
++                done_pkgs.add(n)
++                continue
++            if list_type == 'available' and ipkgs:
++                done_pkgs.add(n)
++                continue
++
++            pkgs = base.pkgSack.searchPkgTuple(pkgtup)
++            if not pkgs:
++                continue
++            if list_type == "updates" and pkgs[0].verLE(ipkgs[0]):
++                done_pkgs.add(n)
++                continue
++            done_pkgs.add(n)
++            data.append((notice, pkgtup, pkgs[0]))
++        show_pkgs(base, md_info, list_type, None, {}, data, msg)
++
++    def _parse_extcmds(self, extcmds):
++        filt_type = None
++        show_type = None
++        if len(extcmds) >= 1:
++            filt_type = None
++            
++            if extcmds[0] in self._cmd2filt:
++                filt_type = self._cmd2filt[extcmds.pop(0)]
++            show_type = filt_type
++            if filt_type and filt_type in _upi._update_info_types_:
++                show_type = None
++        return extcmds, show_type, filt_type
++
++    def doCommand_li(self, base, basecmd, extcmds, show_pkgs):
++        md_info = base.upinfo
++        def msg(x):
++            #  Don't use: logger.log(logginglevels.INFO_2, x)
++            # or -q deletes everything.
++            print x
++
++        opts = _upi._updateinfofilter2opts(base.updateinfo_filters)
++        extcmds, show_type, filt_type = self._parse_extcmds(extcmds)
++
++        list_type = "available"
++        if extcmds and extcmds[0] in ("updates","available","installed", "all"):
++            list_type = extcmds.pop(0)
++
++        if filt_type == "newpackage":
++            # No filtering here, as we want what isn't installed...
++            self.doCommand_li_new(base, list_type, extcmds, md_info, msg,
++                                  show_pkgs)
++            return 0, [basecmd + ' new done']
++
++        opts.sec_cmds = extcmds
++        used_map = _upi._ysp_gen_used_map(base.updateinfo_filters)
++        iname2tup = {}
++        if False: pass
++        elif list_type in ('installed', 'all'):
++            name2tup = _upi._get_name2allpkgtup(base)
++            iname2tup = _upi._get_name2instpkgtup(base)
++        elif list_type == 'updates':
++            name2tup = _upi._get_name2oldpkgtup(base)
++        elif list_type == 'available':
++            name2tup = _upi._get_name2instpkgtup(base)
++
++        def _show_pkgtup(pkgtup):
++            name = pkgtup[0]
++            notices = reversed(md_info.get_applicable_notices(pkgtup))
++            for (pkgtup, notice) in notices:
++                if filt_type and not _upi._ysp_has_info_md(filt_type, notice):
++                    continue
++
++                if list_type == 'installed':
++                    # Remove any that are newer than what we have installed
++                    if _upi._rpm_tup_vercmp(iname2tup[name], pkgtup) < 0:
++                        continue
++
++                if _upi._ysp_should_filter_pkg(opts, name, notice, used_map):
++                    yield (pkgtup, notice)
++
++        data = []
++        for pkgname in sorted(name2tup):
++            for (pkgtup, notice) in _show_pkgtup(name2tup[pkgname]):
++                d = {}
++                (d['n'], d['a'], d['e'], d['v'], d['r']) = pkgtup
++                if d['e'] == '0':
++                    d['epoch'] = ''
++                else:
++                    d['epoch'] = "%s:" % d['e']
++                data.append((notice, pkgtup,
++                            "%(n)s-%(epoch)s%(v)s-%(r)s.%(a)s" % d))
++        show_pkgs(base, md_info, list_type, show_type, iname2tup, data, msg)
++
++        _upi._ysp_chk_used_map(used_map, msg)
++
++        return 0, [basecmd + ' done']
++
++
++class UpdateMinimalCommand(YumCommand):
++    def getNames(self):
++        return ['update-minimal', 'upgrade-minimal']
++
++    def getUsage(self):
++        return "[PACKAGE-wildcard]"
++
++    def getSummary(self):
++        return _("Works like upgrade, but goes to the 'newest' package match which fixes a problem that affects your system")
++
++    def doCheck(self, base, basecmd, extcmds):
++        """Verify that conditions are met so that this command can run.
++        These include that the program is being run by the root user,
++        that there are enabled repositories with gpg keys, and that
++        this command is called with appropriate arguments.
++
++        :param base: a :class:`yum.Yumbase` object
++        :param basecmd: the name of the command
++        :param extcmds: the command line arguments passed to *basecmd*
++        """
++        checkRootUID(base)
++        checkGPGKey(base)
++
++    def doCommand(self, base, basecmd, extcmds):
++        """Execute this command.
++
++        :param base: a :class:`yum.Yumbase` object
++        :param basecmd: the name of the command
++        :param extcmds: the command line arguments passed to *basecmd*
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
++
++        num = len(base.tsInfo)
++        _upi.update_minimal(base, extcmds)
++        num -= len(base.tsInfo)
++        
++        if num > 0:
++            msg = '%d packages marked for minimal Update' % num
++            return 2, [msg]
++        else:
++            return 0, ['No Packages marked for minimal Update']
 diff --git a/yummain.py b/yummain.py
 index 9f79f4f..ac94f65 100755
 --- a/yummain.py
diff --git a/yum.spec b/yum.spec
index e9b0910..6475d4b 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: 83%{?dist}
+Release: 84%{?dist}
 License: GPLv2+
 Group: System Environment/Base
 Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz
@@ -120,6 +120,8 @@ Obsoletes: yum-plugin-downloadonly <= 1.1.31-7.fc18
 Provides: yum-plugin-downloadonly = 3.4.3-44.yum
 Obsoletes: yum-presto < 3.4.3-66.yum
 Provides: yum-presto = 3.4.3-66.yum
+Obsoletes: yum-plugin-security < 1.1.32
+Provides: yum-plugin-security = 3.4.3-84.yum
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 
@@ -149,7 +151,7 @@ can notify you when they are available via email, syslog or dbus.
 %package cron
 Summary: Files needed to run yum updates as a cron job
 Group: System Environment/Base
-Requires: yum >= 3.0 cronie crontabs findutils
+Requires: yum >= 3.4.3-84 cronie crontabs findutils
 %if %{yum_cron_systemd}
 BuildRequires: systemd-units
 Requires(post): systemd
@@ -400,6 +402,13 @@ exit 0
 %endif
 
 %changelog
+* Thu Apr 18 2013 James Antill <james at fedoraproject.org> - 3.4.3-84
+- update to latest HEAD.
+- Move yum-security into core.
+- A bunch of minor fixes for yum-cron.
+- Update yum-cron to add security/minimal/etc. updates.
+- Add socks support to proxy config.
+
 * Tue Apr 16 2013 Zdenek Pavlas <zpavlas at redhat.com> - 3.4.3-83
 - update to latest HEAD.
 - Update yum-cron to make it worthwhile on Fedora.


More information about the scm-commits mailing list