[yum] update to latest HEAD

James Antill james at fedoraproject.org
Wed Mar 4 20:27:50 UTC 2015


commit d4341a12a8e5ddb21b42b226506d720336463708
Author: James Antill <james at and.org>
Date:   Wed Mar 4 15:27:48 2015 -0500

    update to latest HEAD
    
    - Have "yum check" ignore self conflicts.
    - Add simple testcase for installing older intermediate kernel. BZ 1063181.
    - Don't look for upgrades for install only packages. BZ 1063181.
    - check if repos list is empty after excluding disabled repos. BZ 1109473.
    - Allow caching local repos. BZ 1125387.
    - Expect KB as well as MB in disk requirements message from rpm. BZ 1051931.
    - Multiple lvm fixes. BZ 1047793, BZ 1145485.
    - Change the sqlite synchronous mode for the history file, to NORMAL.
    - Add CAShe config. and objects, use it for MD and packages.
    - Add query_install_excludes conf./docs and use it for list/info/search/prov

 yum-HEAD.patch | 1151 ++++++++++++++++++++++++++++++++++----------------------
 yum.spec       |   15 +-
 2 files changed, 717 insertions(+), 449 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index 209b197..b9a2e3d 100644
--- a/yum-HEAD.patch
+++ b/yum-HEAD.patch
@@ -109,7 +109,7 @@ index 2f6154e..2e5a052 100644
 diff --git a/cli.py b/cli.py
 old mode 100644
 new mode 100755
-index 6056d38..b7f5b5a
+index 6056d38..cefc67e
 --- a/cli.py
 +++ b/cli.py
 @@ -25,7 +25,7 @@ import sys
@@ -416,7 +416,7 @@ index 6056d38..b7f5b5a
  
          yumshell = shell.YumShell(base=self)
  
-@@ -382,8 +490,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -382,17 +490,22 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return yumshell.result, yumshell.resultmsgs
  
      def errorSummary(self, errstring):
@@ -430,8 +430,23 @@ index 6056d38..b7f5b5a
 +        """
          summary = ''
          # do disk space report first
-         p = re.compile('needs (\d+)MB on the (\S+) filesystem')
-@@ -407,17 +519,45 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+-        p = re.compile('needs (\d+)MB on the (\S+) filesystem')
++        p = re.compile('needs (\d+)(K|M)B on the (\S+) filesystem')
+         disk = {}
+         for m in p.finditer(errstring):
+-            if m.group(2) not in disk:
+-                disk[m.group(2)] = int(m.group(1))
+-            if disk[m.group(2)] < int(m.group(1)):
+-                disk[m.group(2)] = int(m.group(1))
++            size_in_mb = int(m.group(1)) if m.group(2) == 'M' else round(int(m.group(1))/1024.0, 3)
++            if m.group(3) not in disk:
++                disk[m.group(3)] = size_in_mb
++            if disk[m.group(3)] < size_in_mb:
++                disk[m.group(3)] = size_in_mb
+                 
+         if disk:
+             summary += _('Disk Requirements:\n')
+@@ -407,17 +520,45 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return summary
  
  
@@ -487,7 +502,7 @@ index 6056d38..b7f5b5a
          # 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 +575,40 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -435,14 +576,40 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              try:
                  self._getTs(needTsRemove)
              except yum.Errors.YumBaseError, e:
@@ -533,7 +548,7 @@ index 6056d38..b7f5b5a
          # 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 +619,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -453,7 +620,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)
@@ -542,7 +557,7 @@ index 6056d38..b7f5b5a
              #  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 +629,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -463,7 +630,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          rmpkgs = []
          stuff_to_download = False
          install_only = True
@@ -550,7 +565,7 @@ index 6056d38..b7f5b5a
          for txmbr in self.tsInfo.getMembers():
              if txmbr.ts_state not in ('i', 'u'):
                  install_only = False
-@@ -471,7 +636,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -471,7 +637,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  if po:
                      rmpkgs.append(po)
              else:
@@ -558,7 +573,7 @@ index 6056d38..b7f5b5a
                  stuff_to_download = True
                  po = txmbr.po
                  if po:
-@@ -489,19 +653,40 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -489,19 +654,40 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          else:
              self.reportDownloadSize(downloadpkgs, install_only)
          
@@ -604,7 +619,7 @@ index 6056d38..b7f5b5a
              for key in problems:
                  errors = yum.misc.unique(problems[key])
                  for error in errors:
-@@ -520,8 +705,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -520,8 +706,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
          rcd_st = time.time()
          self.verbose_logger.log(yum.logginglevels.INFO_2, 
@@ -615,7 +630,7 @@ index 6056d38..b7f5b5a
          if msgs:
              rpmlib_only = True
              for msg in msgs:
-@@ -532,21 +718,23 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -532,21 +719,23 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  print _("ERROR You need to update rpm to handle:")
              else:
                  print _('ERROR with transaction check vs depsolve:')
@@ -644,7 +659,7 @@ index 6056d38..b7f5b5a
              
          self.ts.order() # order the transaction
          self.ts.clean() # release memory not needed beyond this point
-@@ -556,16 +744,16 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -556,16 +745,16 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          del testcb
  
          if len(tserrors) > 0:
@@ -664,7 +679,7 @@ index 6056d38..b7f5b5a
          
          # unset the sigquit handler
          signal.signal(signal.SIGQUIT, signal.SIG_DFL)
-@@ -595,9 +783,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -595,9 +784,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          if self.conf.debuglevel < 2:
              cb.display.output = False
  
@@ -690,7 +705,7 @@ index 6056d38..b7f5b5a
          self.verbose_logger.debug('Transaction time: %0.3f' % (time.time() - ts_st))
          # close things
          self.verbose_logger.log(yum.logginglevels.INFO_1,
-@@ -609,12 +812,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -609,12 +813,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return resultobject.return_code
          
      def gpgsigcheck(self, pkgs):
@@ -710,7 +725,7 @@ index 6056d38..b7f5b5a
          for po in pkgs:
              result, errmsg = self.sigCheckPkg(po)
  
-@@ -623,7 +828,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -623,7 +829,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  continue            
  
              elif result == 1:
@@ -720,7 +735,7 @@ index 6056d38..b7f5b5a
                      raise yum.Errors.YumBaseError, \
                              _('Refusing to automatically import keys when running ' \
                              'unattended.\nUse "-y" to override.')
-@@ -691,12 +897,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -691,12 +898,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                                       ", ".join(matches))
              self.verbose_logger.log(yum.logginglevels.INFO_2, msg)
  
@@ -789,7 +804,7 @@ index 6056d38..b7f5b5a
          # get the list of available packages
          # iterate over the user's list
          # add packages to Transaction holding class if they match.
-@@ -710,11 +966,38 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -710,11 +967,38 @@ 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))):
@@ -830,7 +845,7 @@ index 6056d38..b7f5b5a
              except yum.Errors.InstallError:
                  self.verbose_logger.log(yum.logginglevels.INFO_2,
                                          _('No package %s%s%s available.'),
-@@ -723,6 +1006,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -723,6 +1007,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  self._maybeYouMeant(arg)
              else:
                  done = True
@@ -838,7 +853,7 @@ index 6056d38..b7f5b5a
          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 +1016,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -732,9 +1017,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, [_('Nothing to do')]
          
      def updatePkgs(self, userlist, quiet=0, update_to=False):
@@ -869,7 +884,7 @@ index 6056d38..b7f5b5a
          # 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 +1047,46 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -745,34 +1048,46 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
          else:
              # go through the userlist - look for items that are local rpms. If we find them
@@ -933,7 +948,7 @@ index 6056d38..b7f5b5a
  
          level = 'diff'
          if userlist and userlist[0] in ('full', 'diff', 'different'):
-@@ -831,6 +1145,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -831,6 +1146,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                          continue
  
                      nayi = napkg.yumdb_info
@@ -941,7 +956,7 @@ index 6056d38..b7f5b5a
                      for apkg in self.pkgSack.searchPkgTuple(napkg.pkgtup):
                          if ('checksum_type' in nayi and
                              'checksum_data' in nayi and
-@@ -861,19 +1176,58 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -861,19 +1177,58 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  dupdates.extend(self.downgrade(name=n, epoch=e, ver=v, rel=r))
  
          if dupdates:
@@ -1008,7 +1023,7 @@ index 6056d38..b7f5b5a
              if not rms:
                  self._checkMaybeYouMeant(arg, always_output=False, rpmdb_only=True)
              all_rms.extend(rms)
-@@ -884,12 +1238,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -884,12 +1239,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return 0, [_('No Packages marked for removal')]
      
      def downgradePkgs(self, userlist):
@@ -1036,7 +1051,7 @@ index 6056d38..b7f5b5a
          for arg in userlist:
              if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
                                            os.path.exists(arg))):
-@@ -905,26 +1271,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -905,26 +1272,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                                          self.term.MODE['bold'], arg,
                                          self.term.MODE['normal'])
                  self._maybeYouMeant(arg)
@@ -1085,7 +1100,7 @@ index 6056d38..b7f5b5a
              except yum.Errors.ReinstallRemoveError:
                  self._checkMaybeYouMeant(arg, always_output=False)
              except yum.Errors.ReinstallInstallError, e:
-@@ -940,22 +1324,38 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -940,22 +1325,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)
@@ -1128,7 +1143,7 @@ index 6056d38..b7f5b5a
  
          installing = False
          for pkg in filelist:
-@@ -971,23 +1371,29 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -971,23 +1372,29 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return 2, [_('Package(s) to install')]
          return 0, [_('Nothing to do')]
  
@@ -1174,7 +1189,7 @@ index 6056d38..b7f5b5a
          
          pkgnarrow = 'all'
          done_hidden_available = False
-@@ -1003,7 +1409,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1003,7 +1410,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  pkgnarrow = extcmds.pop(0)
              
          ypl = self.doPackageLists(pkgnarrow=pkgnarrow, patterns=extcmds,
@@ -1183,7 +1198,7 @@ index 6056d38..b7f5b5a
          if self.conf.showdupesfromrepos:
              ypl.available += ypl.reinstall_available
  
-@@ -1017,8 +1423,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1017,8 +1424,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return ypl
  
      def search(self, args):
@@ -1211,7 +1226,7 @@ index 6056d38..b7f5b5a
          
          # call the yum module search function with lists of tags to search
          # and what to search for
-@@ -1053,7 +1476,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1053,7 +1477,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                          print ""
                      else:
                          mkeys = set(keys)
@@ -1220,7 +1235,7 @@ index 6056d38..b7f5b5a
                      okeys = keys
                  pos.add(po)
                  akeys.update(keys)
-@@ -1104,13 +1527,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1104,13 +1528,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  self.logger.warning(_('Warning: No matches found for: %s'), arg)
  
          if not akeys:
@@ -1248,7 +1263,7 @@ index 6056d38..b7f5b5a
          pkgs = []
          for arg in args:
              if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
-@@ -1118,10 +1552,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1118,10 +1553,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
                  thispkg = yum.packages.YumUrlPackage(self, self.ts, arg)
                  pkgs.append(thispkg)
              elif self.conf.showdupesfromrepos:
@@ -1263,7 +1278,7 @@ index 6056d38..b7f5b5a
                  except yum.Errors.PackageSackError:
                      pass
                  
-@@ -1131,10 +1567,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1131,10 +1568,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return 0, []
  
      def provides(self, args):
@@ -1287,7 +1302,7 @@ index 6056d38..b7f5b5a
          old_sdup = self.conf.showdupesfromrepos
          # For output, as searchPackageProvides() is always in showdups mode
          self.conf.showdupesfromrepos = True
-@@ -1147,6 +1592,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1147,6 +1593,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              paths = set(sys.path + os.environ['PATH'].split(':'))
              nargs = []
              for arg in args:
@@ -1296,7 +1311,7 @@ index 6056d38..b7f5b5a
                  if yum.misc.re_filename(arg) or yum.misc.re_glob(arg):
                      continue
                  for path in paths:
-@@ -1158,25 +1605,82 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1158,25 +1606,82 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          self.conf.showdupesfromrepos = old_sdup
  
          if len(matching) == 0:
@@ -1385,7 +1400,7 @@ index 6056d38..b7f5b5a
          hdrcode = pkgcode = xmlcode = dbcode = expccode = 0
          pkgresults = hdrresults = xmlresults = dbresults = expcresults = []
          msg = self.fmtKeyValFill(_('Cleaning repos: '), 
-@@ -1184,7 +1688,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1184,7 +1689,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,
@@ -1394,7 +1409,7 @@ index 6056d38..b7f5b5a
              pkgcode, pkgresults = self.cleanPackages()
              hdrcode, hdrresults = self.cleanHeaders()
              xmlcode, xmlresults = self.cleanMetadata()
-@@ -1200,10 +1704,10 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1200,10 +1705,10 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
              return code, []
              
          if 'headers' in userlist:
@@ -1407,7 +1422,7 @@ index 6056d38..b7f5b5a
              pkgcode, pkgresults = self.cleanPackages()
          if 'metadata' in userlist:
              self.logger.debug(_('Cleaning up xml metadata'))
-@@ -1228,159 +1732,345 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1228,159 +1733,345 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return code, []
  
      def returnGroupLists(self, userlist):
@@ -1844,7 +1859,7 @@ index 6056d38..b7f5b5a
              return 0, [_('No packages to remove from groups')]
          else:
              return 2, [P_('%d package to remove', '%d packages to remove', len(pkgs_used)) % len(pkgs_used)]
-@@ -1389,7 +2079,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1389,7 +2080,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
  
      def _promptWanted(self):
          # shortcut for the always-off/always-on options
@@ -1853,7 +1868,7 @@ index 6056d38..b7f5b5a
              return False
          if self.conf.alwaysprompt:
              return True
-@@ -1397,10 +2087,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1397,10 +2088,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          # prompt if:
          #  package was added to fill a dependency
          #  package is being removed
@@ -1865,7 +1880,7 @@ index 6056d38..b7f5b5a
                     txmbr.name not in self.extcmds:
                  return True
          
-@@ -1408,11 +2097,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1408,11 +2098,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return False
  
      def usage(self):
@@ -1879,7 +1894,7 @@ index 6056d38..b7f5b5a
          sys.stdout.write(self.optparser.get_usage())
      
      def _installable(self, pkg, ematch=False):
-@@ -1468,9 +2157,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1468,9 +2158,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
          return False
  
  class YumOptionParser(OptionParser):
@@ -1891,7 +1906,7 @@ index 6056d38..b7f5b5a
  
      def __init__(self,base, **kwargs):
          # check if this is called with a utils=True/False parameter
-@@ -1488,13 +2177,23 @@ class YumOptionParser(OptionParser):
+@@ -1488,13 +2178,23 @@ class YumOptionParser(OptionParser):
          self._addYumBasicOptions()
  
      def error(self, msg):
@@ -1917,7 +1932,7 @@ index 6056d38..b7f5b5a
          try:
              args = _filtercmdline(
                          ('--noplugins','--version','-q', '-v', "--quiet", "--verbose"), 
-@@ -1521,7 +2220,15 @@ class YumOptionParser(OptionParser):
+@@ -1521,7 +2221,15 @@ class YumOptionParser(OptionParser):
          return ret
          
      def setupYumConfig(self, args=None):
@@ -1934,7 +1949,7 @@ index 6056d38..b7f5b5a
          if not args:
              (opts, cmds) = self.parse_args()
          else:
-@@ -1533,16 +2240,30 @@ class YumOptionParser(OptionParser):
+@@ -1533,16 +2241,30 @@ class YumOptionParser(OptionParser):
          try:
              # config file is parsed and moving us forward
              # set some things in it.
@@ -1971,7 +1986,7 @@ index 6056d38..b7f5b5a
                  self.base.conf.cache = 1
  
              if opts.obsoletes:
-@@ -1574,11 +2295,8 @@ class YumOptionParser(OptionParser):
+@@ -1574,13 +2296,11 @@ class YumOptionParser(OptionParser):
                  if opts.color != 'auto':
                      self.base.term.reinit(color=opts.color)
  
@@ -1983,9 +1998,13 @@ index 6056d38..b7f5b5a
 +            self.base.conf.disable_excludes = self._splitArg(opts.disableexcludes)
 +            self.base.conf.disable_includes = self._splitArg(opts.disableincludes)
  
-             for exclude in self._splitArg(opts.exclude):
+-            for exclude in self._splitArg(opts.exclude):
++            self.base.cmdline_excludes = self._splitArg(opts.exclude)
++            for exclude in self.base.cmdline_excludes:
                  try:
-@@ -1610,10 +2328,6 @@ class YumOptionParser(OptionParser):
+                     excludelist = self.base.conf.exclude
+                     excludelist.append(exclude)
+@@ -1610,10 +2330,6 @@ class YumOptionParser(OptionParser):
                      self.base.usage()
                      sys.exit(1)
  
@@ -1996,7 +2015,7 @@ index 6056d38..b7f5b5a
              # Disable all gpg key checking, if requested.
              if opts.nogpgcheck:
                  #  Altering the normal configs. doesn't work too well, esp. with
-@@ -1623,7 +2337,7 @@ class YumOptionParser(OptionParser):
+@@ -1623,7 +2339,7 @@ class YumOptionParser(OptionParser):
                      repo._override_sigchecks = True
                              
          except ValueError, e:
@@ -2005,7 +2024,7 @@ index 6056d38..b7f5b5a
              self.base.usage()
              sys.exit(1)
           
-@@ -1640,10 +2354,18 @@ class YumOptionParser(OptionParser):
+@@ -1640,10 +2356,18 @@ class YumOptionParser(OptionParser):
          sys.exit(1)
  
      def getRoot(self,opts):
@@ -2025,7 +2044,7 @@ index 6056d38..b7f5b5a
              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 +2423,9 @@ class YumOptionParser(OptionParser):
+@@ -1701,6 +2425,9 @@ class YumOptionParser(OptionParser):
          group.add_option("--showduplicates", dest="showdupesfromrepos",
                          action="store_true",
                  help=_("show duplicates, in repos, in list/search commands"))
@@ -2035,7 +2054,7 @@ index 6056d38..b7f5b5a
          group.add_option("-e", "--errorlevel", dest="errorlevel", default=None,
                  help=_("error output level"), type='int',
                  metavar='[error level]')
-@@ -1713,6 +2438,10 @@ class YumOptionParser(OptionParser):
+@@ -1713,6 +2440,10 @@ class YumOptionParser(OptionParser):
                          help=_("verbose operation"))
          group.add_option("-y", "--assumeyes", dest="assumeyes",
                  action="store_true", help=_("answer yes for all questions"))
@@ -2046,7 +2065,7 @@ index 6056d38..b7f5b5a
          group.add_option("--version", action="store_true", 
                  help=_("show Yum version and exit"))
          group.add_option("--installroot", help=_("set install root"), 
-@@ -1730,6 +2459,9 @@ class YumOptionParser(OptionParser):
+@@ -1730,6 +2461,9 @@ class YumOptionParser(OptionParser):
          group.add_option("", "--disableexcludes", default=[], action="append",
                  help=_("disable exclude from main, for a repo or for everything"),
                          metavar='[repo]')
@@ -2056,7 +2075,7 @@ index 6056d38..b7f5b5a
          group.add_option("--obsoletes", action="store_true", 
                  help=_("enable obsoletes processing during updates"))
          group.add_option("--noplugins", action="store_true", 
-@@ -1748,9 +2480,29 @@ class YumOptionParser(OptionParser):
+@@ -1748,9 +2482,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"))
@@ -2853,7 +2872,7 @@ index 0000000..7ce1aef
 + the mailing list, yum at lists.baseurl.org, or consult bugzilla.
 +.fi
 diff --git a/docs/yum.8 b/docs/yum.8
-index 1a8202a..998a5ad 100644
+index 1a8202a..a0038f6 100644
 --- a/docs/yum.8
 +++ b/docs/yum.8
 @@ -25,6 +25,8 @@ gnome\-packagekit application\&.
@@ -3491,7 +3510,7 @@ index 1a8202a..998a5ad 100644
 +.br 
 +
 +.br
-+Configuration Options: \fBfssnap_automatic_pre\fP, \fBfssnap_automatic_post\fP, \fBfssnap_automatic_keep\fP, \fBfssnap_percentage\fP, \fBfssnap_devices\fP
++Configuration Options: \fBfssnap_automatic_pre\fP, \fBfssnap_automatic_post\fP, \fBfssnap_automatic_keep\fP, \fBfssnap_percentage\fP, \fBfssnap_devices\fP, \fBfssnap_abort_on_errors\fP
 +
 +.IP
 +.IP "\fBfs\fP"
@@ -3666,7 +3685,7 @@ index 1a8202a..998a5ad 100644
  http://yum.baseurl.org/wiki/Faq
  yum search yum
 diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
-index 515aa73..97acbe4 100644
+index 515aa73..5c349cb 100644
 --- a/docs/yum.conf.5
 +++ b/docs/yum.conf.5
 @@ -64,7 +64,7 @@ options are: 'critical', 'emergency', 'error', 'warn' and 'debug'.
@@ -3678,7 +3697,7 @@ index 515aa73..97acbe4 100644
  
  The default is: yum glob:/etc/yum/protected.d/*.conf
  So any packages which should be protected can do so by including a file in 
-@@ -114,37 +114,49 @@ are causing problems from the transaction.
+@@ -114,37 +114,59 @@ are causing problems from the transaction.
  Either `1' or `0'. Determines whether or not yum prompts for confirmation of
  critical actions. Default is `0' (do prompt).
  .br
@@ -3733,17 +3752,26 @@ index 515aa73..97acbe4 100644
 +can be used to remove packages in any way that "yum list" will show packages.
  Shell globs using wildcards (eg. * and ?) are allowed.
  
--.IP
++Can be disabled using disable_excludes or --disableexcludes.
++Command-line option: \fB\-x\fP
++
+ .IP
 -\fBexactarch\fR
 -Either `1' or `0'. Set to `1' to make yum update only update the architectures
 -of packages that you have installed. ie: with this enabled yum will not install
 -an i686 package to update an i386 package. Default is `1'.
-+Can be disabled using --disableexcludes.
-+Command-line option: \fB\-x\fP
++\fBdisable_excludes\fR
++A way to permanently set the --disableexcludes command line option.
++
++.IP
++\fBquery_install_excludes\fR
++This applies the command line exclude option (only, not the configuration
++exclude above) to installed packages being shown in some query commands
++(currently: list/info/search/provides).
  
  .IP
  \fBinstallonlypkgs \fR
-@@ -161,7 +173,7 @@ will also apply to kernel-debug-devel, etc.
+@@ -161,7 +183,7 @@ will also apply to kernel-debug-devel, etc.
  Number of packages listed in installonlypkgs to keep installed at the same
  time. Setting to 0 disables this feature. Default is '0'. Note that this
  functionality used to be in the "installonlyn" plugin, where this option was
@@ -3752,7 +3780,7 @@ index 515aa73..97acbe4 100644
  Note that as of version 3.2.24, yum will now look in the yumdb for a installonly
  attribute on installed packages. If that attribute is "keep", then they will
  never be removed.
-@@ -188,12 +200,32 @@ Default is `true'.
+@@ -188,12 +210,32 @@ Default is `true'.
  Command-line option: \fB\-\-obsoletes\fP
  
  .IP
@@ -3785,7 +3813,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fBgroupremove_leaf_only \fR
-@@ -215,6 +247,43 @@ of packages in groups will be installed when 'groupinstall' is called.
+@@ -215,6 +257,43 @@ of packages in groups will be installed when 'groupinstall' is called.
  Default is: default, mandatory
  
  .IP
@@ -3794,7 +3822,7 @@ index 515aa73..97acbe4 100644
 +group install/upgrade/remove commands.
 +
 +Simple acts like you did yum group cmd $(repoquery --group --list group), so
-+it is vrery easy to reason about what will happen. Alas. this is often not what
++it is very easy to reason about what will happen. Alas. this is often not what
 +people want to happen.
 +
 +Compat. works much like simple, except that when you run "group upgrade" it
@@ -3829,7 +3857,7 @@ index 515aa73..97acbe4 100644
  \fBinstallroot \fR
  Specifies an alternative installroot, relative to which all packages will be
  installed. 
-@@ -222,15 +291,34 @@ installed.
+@@ -222,15 +301,34 @@ installed.
  Command-line option: \fB\-\-installroot\fP
  
  .IP
@@ -3868,7 +3896,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fBtsflags\fR
-@@ -240,6 +328,14 @@ with newer rpm versions.
+@@ -240,6 +338,14 @@ with newer rpm versions.
  You can set all/any of them. However, if you don't know what these do in the
  context of an rpm transaction set you're best leaving it alone. Default is
  an empty list.
@@ -3883,7 +3911,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fBrecent\fR
-@@ -291,6 +387,16 @@ the maximum available bandwidth.
+@@ -291,6 +397,16 @@ the maximum available bandwidth.
  
  Set to `0' to disable bandwidth throttling. This is the default.
  
@@ -3900,7 +3928,7 @@ index 515aa73..97acbe4 100644
  .IP
  \fBbandwidth \fR
  Use to specify the maximum available network bandwidth in bytes/second.  Used
-@@ -300,6 +406,50 @@ with the \fBthrottle\fR option (above). If \fBthrottle\fR is a percentage and
+@@ -300,6 +416,50 @@ with the \fBthrottle\fR option (above). If \fBthrottle\fR is a percentage and
  ignored. Default is `0' (no bandwidth throttling). 
  
  .IP
@@ -3951,7 +3979,7 @@ index 515aa73..97acbe4 100644
  \fBsslcacert \fR
  Path to the directory containing the databases of the certificate authorities
  yum should use to verify SSL certificates. Defaults to none - uses system
-@@ -331,6 +481,15 @@ Path to the SSL client key yum should use to connect to repos/remote sites
+@@ -331,6 +491,15 @@ Path to the SSL client key yum should use to connect to repos/remote sites
  Defaults to none.
  
  .IP
@@ -3967,7 +3995,7 @@ index 515aa73..97acbe4 100644
  \fBhistory_record \fR
  Boolean - should yum record history entries for transactions. This takes some
  disk space, and some extra time in the transactions. But it allows how to know a
-@@ -391,7 +550,9 @@ syslog logging is disabled.  Default is `/dev/log'.
+@@ -391,7 +560,9 @@ syslog logging is disabled.  Default is `/dev/log'.
  
  .IP
  \fBproxy \fR
@@ -3978,7 +4006,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fBproxy_username \fR
-@@ -438,6 +599,31 @@ It's also possible to use the word "never", meaning that the metadata will
+@@ -438,6 +609,31 @@ It's also possible to use the word "never", meaning that the metadata will
  never expire. Note that when using a metalink file the metalink must always
  be newer than the metadata for the repository, due to the validation, so this
  timeout also applies to the metalink file.
@@ -4010,7 +4038,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fBmirrorlist_expire \fR
-@@ -462,12 +648,12 @@ always did, however it now does some checking on the index and reverts if
+@@ -462,12 +658,12 @@ always did, however it now does some checking on the index and reverts if
  it classifies it as bad.
  
  `group:primary' - Download the primary metadata with the index. This contains
@@ -4028,7 +4056,7 @@ index 515aa73..97acbe4 100644
  
  `group:main' - With the primary and updateinfo download the filelists metadata
  and the group metadata. The filelists data is required for operations like
-@@ -480,6 +666,19 @@ not listed above is the other metadata, which contains the changelog information
+@@ -480,6 +676,19 @@ not listed above is the other metadata, which contains the changelog information
  which is used by yum-changelog. This is what "yum makecache" uses.
  
  .IP
@@ -4048,7 +4076,7 @@ index 515aa73..97acbe4 100644
  \fBmultilib_policy \fR
  Can be set to 'all' or 'best'. All means install all possible arches for any package you 
  want to install. Therefore yum install foo will install foo.i386 and foo.x86_64 on x86_64, 
-@@ -523,6 +722,13 @@ Default is `normal'.
+@@ -523,6 +732,13 @@ Default is `normal'.
  See color_list_installed_older for possible values.
  
  .IP
@@ -4062,7 +4090,7 @@ index 515aa73..97acbe4 100644
  \fBcolor_list_installed_extra \fR
  The colorization/highlighting for packages in list/info installed which has
  no available package with the same name and arch.
-@@ -558,6 +764,13 @@ Default is `bold,underline,green.
+@@ -558,6 +774,13 @@ Default is `bold,underline,green.
  See color_list_installed_older for possible values.
  
  .IP
@@ -4076,7 +4104,7 @@ index 515aa73..97acbe4 100644
  \fBcolor_search_match \fR
  The colorization/highlighting for text matches in search.
  Default is `bold'.
-@@ -587,15 +800,104 @@ be downloaded. The updates list is what is printed when you run "yum update",
+@@ -587,15 +810,119 @@ be downloaded. The updates list is what is printed when you run "yum update",
  Default is `normal'.
  See color_list_installed_older for possible values.
  
@@ -4153,7 +4181,7 @@ index 515aa73..97acbe4 100644
 +.IP
 +\fBfssnap_automatic_keep\fR
 +How many old snapshots should yum keep when trying to automatically create a 
-+new snapshot. Setting to 0 disables this feature. Default is '0'.
++new snapshot. Setting to 0 disables this feature. Default is '1'.
 +
 +.IP
 +\fBfssnap_automatic_percentage\fR
@@ -4167,6 +4195,21 @@ index 515aa73..97acbe4 100644
 +Default is: !*/swap !*/lv_swap glob:/etc/yum/fssnap.d/*.conf
 +
 +.IP
++\fBfssnap_abort_on_errors\fR
++When fssnap_automatic_pre or fssnap_automatic_post is enabled, it's possible to specify which
++fssnap errors should make the transaction fail. The default is `any'.
++
++`broken-setup' - Abort current transaction if snapshot support is unavailable because
++lvm is missing or broken.
++
++`snapshot-failure' - Abort current transaction if creating a snapshot fails (e.g. there is not enough
++free space to make a snapshot).
++
++`any' - Abort current transaction if any of the above occurs.
++
++`none' - Never abort a transaction in case of errors.
++
++.IP
 +\fBdepsolve_loop_limit\fR
 +Set the number of times any attempt to depsolve before we just give up. This
 +shouldn't be needed as yum should always solve or fail, however it has been
@@ -4181,7 +4224,7 @@ index 515aa73..97acbe4 100644
  
  .SH "[repository] OPTIONS"
  .LP 
-@@ -668,6 +970,10 @@ value of mirrorlist is copied to metalink (if metalink is not set).
+@@ -668,6 +995,10 @@ value of mirrorlist is copied to metalink (if metalink is not set).
  Either `1' or `0'. This tells yum whether or not use this repository.
  
  .IP
@@ -4192,7 +4235,7 @@ index 515aa73..97acbe4 100644
  \fBgpgcheck\fR
  Either `1' or `0'. This tells yum whether or not it should perform a GPG
  signature check on the packages gotten from this repository.
-@@ -702,12 +1008,18 @@ key will be automatically imported without user confirmation.
+@@ -702,12 +1033,18 @@ key will be automatically imported without user confirmation.
  Same as the [main] \fBexclude\fR option but only for this repository.
  Substitution variables, described below, are honored here.
  
@@ -4215,7 +4258,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fBenablegroups\fR
-@@ -755,6 +1067,20 @@ repository.
+@@ -755,6 +1092,20 @@ repository.
  Overrides the \fBbandwidth\fR option from the [main] section for this
  repository.
  
@@ -4236,7 +4279,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fBsslcacert \fR
-@@ -776,6 +1102,10 @@ repository.
+@@ -776,6 +1127,10 @@ repository.
  Overrides the \fBsslclientkey\fR option from the [main] section for this
  repository.
  
@@ -4247,7 +4290,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fBmetadata_expire \fR
-@@ -783,6 +1113,11 @@ Overrides the \fBmetadata_expire\fR option from the [main] section for this
+@@ -783,6 +1138,11 @@ Overrides the \fBmetadata_expire\fR option from the [main] section for this
  repository.
  
  .IP
@@ -4259,7 +4302,7 @@ index 515aa73..97acbe4 100644
  \fBmirrorlist_expire \fR
  Overrides the \fBmirrorlist_expire\fR option from the [main] section for this
  repository.
-@@ -824,7 +1159,16 @@ as greater/less than any other. defaults to 1000
+@@ -824,7 +1184,16 @@ as greater/less than any other. defaults to 1000
  If set to True yum will continue running if this repository cannot be 
  contacted for any reason. This should be set carefully as all repos are consulted
  for any given command. Defaults to False.
@@ -4276,7 +4319,7 @@ index 515aa73..97acbe4 100644
  
  .SH "URL INCLUDE SYNTAX"
  .LP
-@@ -861,8 +1205,8 @@ package.
+@@ -861,8 +1230,8 @@ package.
  
  .IP
  \fB$arch\fR
@@ -4287,7 +4330,7 @@ index 515aa73..97acbe4 100644
  
  .IP
  \fB$basearch\fR
-@@ -882,8 +1226,10 @@ the same name. If the shell environment variable does not exist then the
+@@ -882,8 +1251,10 @@ the same name. If the shell environment variable does not exist then the
  configuration file variable will not be replaced.
  
  .LP
@@ -5414,7 +5457,7 @@ index e587f96..e716c01 100644
      create 0600 root root
  }
 diff --git a/output.py b/output.py
-index b6aa277..2787d86 100755
+index b6aa277..091b58e 100755
 --- a/output.py
 +++ b/output.py
 @@ -1,6 +1,6 @@
@@ -6264,7 +6307,7 @@ index b6aa277..2787d86 100755
          symbols = [ ' ', # (none)
                      'k', # kilo
                      'M', # mega
-@@ -870,16 +1305,31 @@ class YumOutput:
+@@ -870,15 +1305,37 @@ class YumOutput:
  
      @staticmethod
      def format_time(seconds, use_hours=0):
@@ -6288,7 +6331,6 @@ index b6aa277..2787d86 100755
 -            If matchfor is passed, all the strings in that list will be
 -            highlighted within the output.
 -            verbose overrides logginglevel, if passed. """
--
 +        """Output search/provides type callback matches.
 +
 +        :param po: the package object that matched the search
@@ -6299,10 +6341,16 @@ index b6aa277..2787d86 100755
 +        :param verbose: whether to output extra verbose information
 +        :param highlight: highlighting options for the highlighted matches
 +        """
++        if (po.repo.id == "installed" and
++            self.conf.query_install_excludes and self.cmdline_excludes):
++            # Very similar to _cmdline_exclude from yumcommands
++            e,m,u = yum.packages.parsePackages([po], self.cmdline_excludes)
++            if e or m:
++                return
+ 
          if self.conf.showdupesfromrepos:
              msg = '%s : ' % po
-         else:
-@@ -923,7 +1373,15 @@ class YumOutput:
+@@ -923,7 +1380,15 @@ class YumOutput:
                  item = self._enc(item)
                  can_overflow = False
              else:
@@ -6319,7 +6367,7 @@ index b6aa277..2787d86 100755
  
              if matchfor:
                  item = self._sub_highlight(item, highlight, matchfor,
-@@ -935,14 +1393,34 @@ class YumOutput:
+@@ -935,14 +1400,34 @@ class YumOutput:
          print '\n\n'
  
      def matchcallback_verbose(self, po, values, matchfor=None):
@@ -6355,7 +6403,7 @@ index b6aa277..2787d86 100755
          for pkg in packages:
              # Just to be on the safe side, if for some reason getting
              # the package size fails, log the error and don't report download
-@@ -971,18 +1449,18 @@ class YumOutput:
+@@ -971,18 +1456,18 @@ class YumOutput:
  
          if (not error):
              if locsize:
@@ -6382,7 +6430,7 @@ index b6aa277..2787d86 100755
          totsize = 0
          error = False
          for pkg in packages:
-@@ -997,13 +1475,19 @@ class YumOutput:
+@@ -997,13 +1482,19 @@ class YumOutput:
                  self.logger.error(_('There was an error calculating installed size'))
                  break
          if (not error):
@@ -6407,7 +6455,7 @@ index b6aa277..2787d86 100755
          self.tsInfo.makelists(True, True)
          pkglist_lines = []
          data  = {'n' : {}, 'v' : {}, 'r' : {}}
-@@ -1032,11 +1516,43 @@ class YumOutput:
+@@ -1032,11 +1523,43 @@ class YumOutput:
              for (d, v) in (("n",len(n)), ("v",len(evr)), ("r",len(repoid))):
                  data[d].setdefault(v, 0)
                  data[d][v] += 1
@@ -6454,7 +6502,7 @@ index b6aa277..2787d86 100755
                              (_('Updating'), self.tsInfo.updated),
                              (_('Removing'), self.tsInfo.removed),
                              (_('Reinstalling'), self.tsInfo.reinstalled),
-@@ -1102,19 +1618,72 @@ class YumOutput:
+@@ -1102,19 +1625,72 @@ class YumOutput:
  Transaction Summary
  %s
  """) % ('=' * self.term.columns))
@@ -6537,7 +6585,7 @@ index b6aa277..2787d86 100755
          out = ''
          
          self.tsInfo.makelists()
-@@ -1179,17 +1748,19 @@ Transaction Summary
+@@ -1179,17 +1755,19 @@ Transaction Summary
          return out
  
      def setupProgressCallbacks(self):
@@ -6560,7 +6608,7 @@ index b6aa277..2787d86 100755
              callback = CacheProgressCallback()
  
          # setup our failure report for failover
-@@ -1200,13 +1771,14 @@ Transaction Summary
+@@ -1200,13 +1778,14 @@ Transaction Summary
          interrupt_callback = self.interrupt_callback
          if hasattr(self, 'prerepoconf'):
              self.prerepoconf.progressbar = progressbar
@@ -6576,7 +6624,7 @@ index b6aa277..2787d86 100755
              self.repos.callback = callback
              self.repos.setFailureCallback(failure_callback)
              self.repos.setInterruptCallback(interrupt_callback)
-@@ -1216,10 +1788,12 @@ Transaction Summary
+@@ -1216,10 +1795,12 @@ Transaction Summary
          self.dsCallback = dscb
      
      def setupProgessCallbacks(self):
@@ -6590,27 +6638,27 @@ index b6aa277..2787d86 100755
          confirm_func = self._cli_confirm_gpg_key_import
          gpg_import_func = self.getKeyForRepo
          gpgca_import_func = self.getCAKeyForRepo
-@@ -1233,14 +1807,12 @@ Transaction Summary
+@@ -1233,14 +1814,12 @@ Transaction Summary
              self.repos.gpgca_import_func = gpgca_import_func
  
      def interrupt_callback(self, cbobj):
 -        '''Handle CTRL-C's during downloads
--
--        If a CTRL-C occurs a URLGrabError will be raised to push the download
--        onto the next mirror.  
--        
--        If two CTRL-C's occur in quick succession then yum will exit.
 +        '''Handle CTRL-C's during downloads.  If a CTRL-C occurs a
 +        URLGrabError will be raised to push the download onto the next
 +        mirror.  If two CTRL-C's occur in quick succession then yum
 +        will exit.
  
+-        If a CTRL-C occurs a URLGrabError will be raised to push the download
+-        onto the next mirror.  
+-        
+-        If two CTRL-C's occur in quick succession then yum will exit.
+-
 -        @param cbobj: urlgrabber callback obj
 +        :param cbobj: :class:`urlgrabber.grabber.CallbackObject`
          '''
          delta_exit_chk = 2.0      # Delta between C-c's so we treat as exit
          delta_exit_str = _("two") # Human readable version of above
-@@ -1253,7 +1825,7 @@ Transaction Summary
+@@ -1253,7 +1832,7 @@ Transaction Summary
              # For translators: This is output like:
  #  Current download cancelled, interrupt (ctrl-c) again within two seconds
  # to exit.
@@ -6619,7 +6667,7 @@ index b6aa277..2787d86 100755
              msg = _("""
   Current download cancelled, %sinterrupt (ctrl-c) again%s within %s%s%s seconds
  to exit.
-@@ -1269,6 +1841,14 @@ to exit.
+@@ -1269,6 +1848,14 @@ to exit.
  
      def download_callback_total_cb(self, remote_pkgs, remote_size,
                                     download_start_timestamp):
@@ -6634,7 +6682,7 @@ index b6aa277..2787d86 100755
          if len(remote_pkgs) <= 1:
              return
          if not hasattr(urlgrabber.progress, 'TerminalLine'):
-@@ -1280,7 +1860,7 @@ to exit.
+@@ -1280,7 +1867,7 @@ to exit.
          if dl_time <= 0: # This stops divide by zero, among other problems
              dl_time = 0.01
          ui_size = tl.add(' | %5sB' % self.format_number(remote_size))
@@ -6643,17 +6691,17 @@ index b6aa277..2787d86 100755
          ui_end  = tl.add(' ' * 5)
          ui_bs   = tl.add(' %5sB/s' % self.format_number(remote_size / dl_time))
          msg = "%s%s%s%s%s" % (utf8_width_fill(_("Total"), tl.rest(), tl.rest()),
-@@ -1434,10 +2014,21 @@ to exit.
+@@ -1434,10 +2021,21 @@ to exit.
          return tids, printall
  
      def historyListCmd(self, extcmds):
 -        """ Shows the user a list of data about the history. """
 +        """Output a list of information about the history of yum
 +        transactions.
- 
++
 +        :param extcmds: list of extra command line arguments
 +        :return: (exit_code, [errors])
-+
+ 
 +        exit_code is::
 +
 +            0 = we're done, exit
@@ -6666,7 +6714,7 @@ index b6aa277..2787d86 100755
              return 1, ['Failed history list']
  
          limit = 20
-@@ -1564,6 +2155,16 @@ to exit.
+@@ -1564,6 +2162,16 @@ to exit.
          return old[0]
  
      def historyInfoCmd(self, extcmds):
@@ -6683,7 +6731,7 @@ index b6aa277..2787d86 100755
          def str2int(x):
              try:
                  return int(x)
-@@ -1656,6 +2257,9 @@ to exit.
+@@ -1656,6 +2264,9 @@ to exit.
      def _hpkg2from_repo(self, hpkg):
          """ Given a pkg, find the ipkg.ui_from_repo ... if none, then
              get an apkg. ... and put a ? in there. """
@@ -6693,7 +6741,7 @@ index b6aa277..2787d86 100755
          ipkgs = self.rpmdb.searchPkgTuple(hpkg.pkgtup)
          if not ipkgs:
              apkgs = self.pkgSack.searchPkgTuple(hpkg.pkgtup)
-@@ -1672,13 +2276,12 @@ to exit.
+@@ -1672,13 +2283,12 @@ to exit.
                                   'o' : _('Updated'), 'n' : _('Downgraded')}
          _pkg_states_available = {'i' : _('Installed'), 'e' : _('Not installed'),
                                   'o' : _('Older'), 'n' : _('Newer')}
@@ -6710,7 +6758,7 @@ index b6aa277..2787d86 100755
              prefix = " " * prefix_len
              if was_installed:
                  _pkg_states = _pkg_states_installed
-@@ -1702,9 +2305,11 @@ to exit.
+@@ -1702,9 +2312,11 @@ to exit.
              else:
                  (hibeg, hiend) = self._highlight('normal')
              state = utf8_width_fill(state, _pkg_states['maxlen'])
@@ -6724,7 +6772,7 @@ index b6aa277..2787d86 100755
  
          if type(old.tid) == type([]):
              print _("Transaction ID :"), "%u..%u" % (old.tid[0], old.tid[-1])
-@@ -1778,8 +2383,8 @@ to exit.
+@@ -1778,8 +2390,8 @@ to exit.
              default_addons = set(['config-main', 'config-repos', 'saved_tx'])
              non_default = set(addon_info).difference(default_addons)
              if len(non_default) > 0:
@@ -6735,7 +6783,7 @@ index b6aa277..2787d86 100755
  
          if old.trans_with:
              # This is _possible_, but not common
-@@ -1794,7 +2399,9 @@ to exit.
+@@ -1794,7 +2406,9 @@ to exit.
              print _("Packages Skipped:")
              pkg_max_len = max((len(str(hpkg)) for hpkg in old.trans_skip))
          for hpkg in old.trans_skip:
@@ -6746,7 +6794,7 @@ index b6aa277..2787d86 100755
  
          if old.rpmdb_problems:
              print _("Rpmdb Problems:")
-@@ -1833,6 +2440,13 @@ to exit.
+@@ -1833,6 +2447,13 @@ to exit.
                                'Updated'      : _('Updated'),
                                }
      def historyInfoCmdPkgsAltered(self, old, pats=[]):
@@ -6760,7 +6808,7 @@ index b6aa277..2787d86 100755
          last = None
          #  Note that these don't use _simple_pkg() because we are showing what
          # happened to them in the transaction ... not the difference between the
-@@ -1886,6 +2500,10 @@ to exit.
+@@ -1886,6 +2507,10 @@ to exit.
                                          self._hpkg2from_repo(hpkg))
  
      def historySummaryCmd(self, extcmds):
@@ -6771,7 +6819,7 @@ index b6aa277..2787d86 100755
          tids, printall = self._history_list_transactions(extcmds)
          if tids is None:
              return 1, ['Failed history info']
-@@ -1946,6 +2564,10 @@ to exit.
+@@ -1946,6 +2571,10 @@ to exit.
                               utf8_width_fill(uiacts, 16, 16), count)
  
      def historyAddonInfoCmd(self, extcmds):
@@ -6782,7 +6830,7 @@ index b6aa277..2787d86 100755
          tid = None
          if len(extcmds) > 1:
              tid = extcmds[1]
-@@ -1983,16 +2605,19 @@ to exit.
+@@ -1983,16 +2612,19 @@ to exit.
          
          for item in extcmds[2:]:
              if item in addon_info:
@@ -6808,7 +6856,7 @@ index b6aa277..2787d86 100755
          tids = self.history.search(extcmds)
          limit = None
          if extcmds and not tids:
-@@ -2078,9 +2703,94 @@ to exit.
+@@ -2078,9 +2710,94 @@ to exit.
              if lastdbv.end_rpmdbversion != rpmdbv:
                  self._rpmdb_warn_checks()
  
@@ -6904,7 +6952,7 @@ index b6aa277..2787d86 100755
      
      def __init__(self, ayum=None):
          """requires yum-cli log and errorlog functions as arguments"""
-@@ -2089,6 +2799,25 @@ class DepSolveProgressCallBack:
+@@ -2089,6 +2806,25 @@ class DepSolveProgressCallBack:
          self.ayum = ayum
  
      def pkgAdded(self, pkgtup, mode):
@@ -6930,7 +6978,7 @@ index b6aa277..2787d86 100755
          modedict = { 'i': _('installed'),
                       'u': _('an update'),
                       'e': _('erased'),
-@@ -2104,43 +2833,86 @@ class DepSolveProgressCallBack:
+@@ -2104,43 +2840,86 @@ class DepSolveProgressCallBack:
              modeterm)
          
      def start(self):
@@ -7021,7 +7069,7 @@ index b6aa277..2787d86 100755
          needname, needflags, needversion = reqTup
  
          yb = self.ayum
-@@ -2164,6 +2936,18 @@ class DepSolveProgressCallBack:
+@@ -2164,6 +2943,18 @@ class DepSolveProgressCallBack:
                  done = True
                  msg += _('\n        %s') % yum.misc.prco_tuple_to_string(pkgtup)
              if not done:
@@ -7040,7 +7088,7 @@ index b6aa277..2787d86 100755
                  msg += _('\n        Not found')
              return msg
  
-@@ -2225,46 +3009,106 @@ class DepSolveProgressCallBack:
+@@ -2225,46 +3016,106 @@ class DepSolveProgressCallBack:
          return msg
      
      def procConflict(self, name, confname):
@@ -7152,7 +7200,7 @@ index b6aa277..2787d86 100755
  
  def _pkgname_ui(ayum, pkgname, ts_states=None):
      """ Get more information on a simple pkgname, if we can. We need to search
-@@ -2316,10 +3160,7 @@ def _pkgname_ui(ayum, pkgname, ts_states=None):
+@@ -2316,10 +3167,7 @@ def _pkgname_ui(ayum, pkgname, ts_states=None):
      return pkgname
  
  class YumCliRPMCallBack(RPMBaseCallback):
@@ -7164,7 +7212,7 @@ index b6aa277..2787d86 100755
  
      width = property(lambda x: _term_width())
  
-@@ -2337,21 +3178,34 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2337,21 +3185,34 @@ class YumCliRPMCallBack(RPMBaseCallback):
      #  Installing things have pkg objects passed to the events, so only need to
      # lookup for erased/obsoleted.
      def pkgname_ui(self, pkgname, ts_states=('e', 'od', 'ud', None)):
@@ -7209,7 +7257,7 @@ index b6aa277..2787d86 100755
          
          if type(package) not in types.StringTypes:
              pkgname = str(package)
-@@ -2363,9 +3217,25 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2363,9 +3224,25 @@ class YumCliRPMCallBack(RPMBaseCallback):
              percent = 0
          else:
              percent = (te_current*100L)/te_total
@@ -7236,7 +7284,7 @@ index b6aa277..2787d86 100755
                                                pkgname=pkgname, wid1=wid1)
              msg = fmt % (utf8_width_fill(process, wid1, wid1),
                           utf8_width_fill(pkgname, wid2, wid2))
-@@ -2377,6 +3247,11 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2377,6 +3254,11 @@ class YumCliRPMCallBack(RPMBaseCallback):
                  print " "
  
      def scriptout(self, package, msgs):
@@ -7248,7 +7296,7 @@ index b6aa277..2787d86 100755
          if msgs:
              sys.stdout.write(to_unicode(msgs))
              sys.stdout.flush()
-@@ -2396,7 +3271,7 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2396,7 +3278,7 @@ class YumCliRPMCallBack(RPMBaseCallback):
              pnl = utf8_width(pkgname)
  
          overhead  = (2 * l) + 2 # Length of done, above
@@ -7257,7 +7305,7 @@ index b6aa277..2787d86 100755
          overhead +=  1          # Space between pn and done
          overhead +=  2          # Ends for progress
          overhead +=  1          # Space for end
-@@ -2429,8 +3304,30 @@ class YumCliRPMCallBack(RPMBaseCallback):
+@@ -2429,8 +3311,30 @@ class YumCliRPMCallBack(RPMBaseCallback):
              wid2 = pnl
          return fmt, wid1, wid2
  
@@ -188110,10 +188158,10 @@ index 97a9923..6cede1e 100644
  
      @staticmethod
 diff --git a/test/simpleupdatetests.py b/test/simpleupdatetests.py
-index 6177fb1..bc74de6 100644
+index 6177fb1..0c981c5 100644
 --- a/test/simpleupdatetests.py
 +++ b/test/simpleupdatetests.py
-@@ -990,3 +990,262 @@ class SimpleUpdateTests(OperationsTests):
+@@ -990,3 +990,277 @@ class SimpleUpdateTests(OperationsTests):
          # Nothing to do...
          self.assert_(res==0, msg)
  
@@ -188376,6 +188424,21 @@ index 6177fb1..bc74de6 100644
 +
 +        self.assert_(res=='ok', msg)
 +        self.assertResult((bar11,baz12))
++
++    def testInstall_kernel_intermediate(self):
++        #  Make sure we don't break this again...
++        k11 = FakePackage('kernel', '1', '1', '0', 'i386')
++        k12 = FakePackage('kernel', '1', '2', '0', 'i386')
++        k13 = FakePackage('kernel', '1', '3', '0', 'i386')
++        k14 = FakePackage('kernel', '1', '4', '0', 'i386')
++        k15 = FakePackage('kernel', '1', '5', '0', 'i386')
++
++        res, msg = self.runOperation(['install', 'kernel-1-2'],
++                                     [k11, k13, k14],
++                                     [k11, k12, k13, k14, k15])
++
++        self.assert_(res=='ok', msg)
++        self.assertResult((k11, k12, k13, k14))
 diff --git a/test/skipbroken-tests.py b/test/skipbroken-tests.py
 index 812785a..e2abc4c 100644
 --- a/test/skipbroken-tests.py
@@ -191426,7 +191489,7 @@ index c1af4ad..f69c061 100644
      pass
      
 diff --git a/yum/__init__.py b/yum/__init__.py
-index 99039e0..a8a4e80 100644
+index 99039e0..c62af2c 100644
 --- a/yum/__init__.py
 +++ b/yum/__init__.py
 @@ -21,6 +21,7 @@ The Yum RPM software updater.
@@ -191476,7 +191539,19 @@ index 99039e0..a8a4e80 100644
  
  import string
  import StringIO
-@@ -102,10 +113,12 @@ default_grabber.opts.user_agent += " yum/" + __version__
+@@ -91,6 +102,11 @@ from weakref import proxy as weakref
+ 
+ from urlgrabber.grabber import default_grabber
+ 
++try:
++    import cashe
++except ImportError:
++    cashe = None
++
+ __version__ = '3.4.3'
+ __version_info__ = tuple([ int(num) for num in __version__.split('.')])
+ 
+@@ -102,10 +118,12 @@ default_grabber.opts.user_agent += " yum/" + __version__
  
  
  class _YumPreBaseConf:
@@ -191493,7 +191568,7 @@ index 99039e0..a8a4e80 100644
      def __init__(self):
          self.fn = '/etc/yum/yum.conf'
          self.root = '/'
-@@ -125,12 +138,15 @@ class _YumPreBaseConf:
+@@ -125,12 +143,15 @@ class _YumPreBaseConf:
  
  
  class _YumPreRepoConf:
@@ -191513,7 +191588,7 @@ index 99039e0..a8a4e80 100644
          self.callback = None
          self.failure_callback = None
          self.interrupt_callback = None
-@@ -164,11 +180,11 @@ class _YumCostExclude:
+@@ -164,11 +185,11 @@ class _YumCostExclude:
          return False
  
  class YumBase(depsolve.Depsolve):
@@ -191530,7 +191605,7 @@ index 99039e0..a8a4e80 100644
      def __init__(self):
          depsolve.Depsolve.__init__(self)
          self._conf = None
-@@ -177,9 +193,12 @@ class YumBase(depsolve.Depsolve):
+@@ -177,9 +198,12 @@ class YumBase(depsolve.Depsolve):
          self._up = None
          self._comps = None
          self._history = None
@@ -191543,7 +191618,7 @@ index 99039e0..a8a4e80 100644
          self._ts_save_file = None
          self.skipped_packages = []   # packages skip by the skip-broken code
          self._not_found_a = {}
-@@ -204,6 +223,9 @@ class YumBase(depsolve.Depsolve):
+@@ -204,6 +228,9 @@ class YumBase(depsolve.Depsolve):
  
          self.run_with_package_names = set()
          self._cleanup = []
@@ -191553,7 +191628,7 @@ index 99039e0..a8a4e80 100644
  
      def __del__(self):
          self.close()
-@@ -213,10 +235,15 @@ class YumBase(depsolve.Depsolve):
+@@ -213,10 +240,15 @@ class YumBase(depsolve.Depsolve):
          for cb in self._cleanup: cb()
  
      def close(self):
@@ -191569,7 +191644,7 @@ index 99039e0..a8a4e80 100644
          if self._repos:
              self._repos.close()
  
-@@ -225,15 +252,33 @@ class YumBase(depsolve.Depsolve):
+@@ -225,15 +257,33 @@ class YumBase(depsolve.Depsolve):
          return transactioninfo.TransactionData()
  
      def doGenericSetup(self, cache=0):
@@ -191605,7 +191680,7 @@ index 99039e0..a8a4e80 100644
          warnings.warn(_('doConfigSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -297,15 +342,17 @@ class YumBase(depsolve.Depsolve):
+@@ -297,15 +347,17 @@ class YumBase(depsolve.Depsolve):
              # Try the old default
              fn = '/etc/yum.conf'
  
@@ -191626,7 +191701,7 @@ index 99039e0..a8a4e80 100644
  
          if debuglevel != None:
              startupconf.debuglevel = debuglevel
-@@ -336,6 +383,12 @@ class YumBase(depsolve.Depsolve):
+@@ -336,6 +388,12 @@ class YumBase(depsolve.Depsolve):
  
          self._conf = config.readMainConfig(startupconf)
  
@@ -191639,7 +191714,18 @@ index 99039e0..a8a4e80 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 +420,36 @@ class YumBase(depsolve.Depsolve):
+@@ -344,6 +402,10 @@ class YumBase(depsolve.Depsolve):
+         for pkgname in self.conf.history_record_packages:
+             self.run_with_package_names.add(pkgname)
+ 
++        self._cashe = None
++        if cashe is not None:
++            self._cashe = cashe.CAShe(self.conf.cashedir)
++
+         # run the postconfig plugin hook
+         self.plugins.run('postconfig')
+         #  Note that Pungi has historically replaced _getConfig(), and it sets
+@@ -367,22 +429,36 @@ class YumBase(depsolve.Depsolve):
      def doLoggingSetup(self, debuglevel, errorlevel,
                         syslog_ident=None, syslog_facility=None,
                         syslog_device='/dev/log'):
@@ -191683,7 +191769,7 @@ index 99039e0..a8a4e80 100644
          if repo_age is None:
              repo_age = os.stat(repofn)[8]
          
-@@ -391,8 +458,7 @@ class YumBase(depsolve.Depsolve):
+@@ -391,8 +467,7 @@ class YumBase(depsolve.Depsolve):
          try:
              parser.readfp(confpp_obj)
          except ParsingError, e:
@@ -191693,7 +191779,7 @@ index 99039e0..a8a4e80 100644
  
          # Check sections in the .repo file that was just slurped up
          for section in parser.sections():
-@@ -429,17 +495,41 @@ class YumBase(depsolve.Depsolve):
+@@ -429,17 +504,41 @@ class YumBase(depsolve.Depsolve):
  
                  thisrepo.base_persistdir = self.conf._repos_persistdir
  
@@ -191738,7 +191824,7 @@ index 99039e0..a8a4e80 100644
              # Got our list of repo objects, add them to the repos
              # collection
              try:
-@@ -447,9 +537,18 @@ class YumBase(depsolve.Depsolve):
+@@ -447,9 +546,18 @@ class YumBase(depsolve.Depsolve):
              except Errors.RepoError, e:
                  self.logger.warning(e)
          
@@ -191759,7 +191845,7 @@ index 99039e0..a8a4e80 100644
          # Read .repo files from directories specified by the reposdir option
          # (typically /etc/yum/repos.d)
          repo_config_age = self.conf.config_file_age
-@@ -463,21 +562,26 @@ class YumBase(depsolve.Depsolve):
+@@ -463,21 +571,26 @@ class YumBase(depsolve.Depsolve):
              # if we don't do this then anaconda likes to not  work.
              if os.path.exists(self.conf.installroot+'/'+reposdir):
                  reposdir = self.conf.installroot + '/' + reposdir
@@ -191791,17 +191877,21 @@ index 99039e0..a8a4e80 100644
          repo = yumRepo.YumRepository(section)
          try:
              repo.populate(parser, section, self.conf)
-@@ -493,38 +597,40 @@ class YumBase(depsolve.Depsolve):
+@@ -493,38 +606,44 @@ class YumBase(depsolve.Depsolve):
          repo.name = to_unicode(repo.name)
  
          # Set attributes not from the config file
 +        repo.old_base_cache_dir = getattr(self, '_old_cachedir', '')
          repo.basecachedir = self.conf.cachedir
          repo.yumvar.update(self.conf.yumvar)
++        repo._cashe = self._cashe
          repo.cfg = parser
 -
 +        # Enable parallel downloading
 +        repo._async = repo.async
++        # Allow caching local repos
++        if repo.keepcache and any(u.startswith('file:') for u in repo.baseurl):
++            repo.copy_local = True
          return repo
  
      def disablePlugins(self):
@@ -191854,7 +191944,7 @@ index 99039e0..a8a4e80 100644
          if isinstance(self.plugins, plugins.YumPlugins):
              raise RuntimeError(_("plugins already initialised"))
  
-@@ -533,6 +639,8 @@ class YumBase(depsolve.Depsolve):
+@@ -533,6 +652,8 @@ class YumBase(depsolve.Depsolve):
  
      
      def doRpmDBSetup(self):
@@ -191863,7 +191953,7 @@ index 99039e0..a8a4e80 100644
          warnings.warn(_('doRpmDBSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -552,7 +660,8 @@ class YumBase(depsolve.Depsolve):
+@@ -552,7 +673,8 @@ class YumBase(depsolve.Depsolve):
          return self._rpmdb
  
      def closeRpmDB(self):
@@ -191873,7 +191963,7 @@ index 99039e0..a8a4e80 100644
          if self._rpmdb is not None:
              self._rpmdb.ts = None
              self._rpmdb.dropCachedData()
-@@ -561,12 +670,19 @@ class YumBase(depsolve.Depsolve):
+@@ -561,12 +683,19 @@ class YumBase(depsolve.Depsolve):
          self._tsInfo = None
          self._up = None
          self.comps = None
@@ -191893,7 +191983,7 @@ index 99039e0..a8a4e80 100644
          warnings.warn(_('doRepoSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -577,6 +693,12 @@ class YumBase(depsolve.Depsolve):
+@@ -577,6 +706,12 @@ class YumBase(depsolve.Depsolve):
          if hasattr(self, 'prerepoconf'):
              self.conf # touch the config class first
  
@@ -191906,7 +191996,7 @@ index 99039e0..a8a4e80 100644
              self.getReposFromConfig()
  
          #  For rhnplugin, and in theory other stuff, calling
-@@ -588,7 +710,8 @@ class YumBase(depsolve.Depsolve):
+@@ -588,7 +723,8 @@ class YumBase(depsolve.Depsolve):
              prerepoconf = self.prerepoconf
              del self.prerepoconf
  
@@ -191916,7 +192006,7 @@ index 99039e0..a8a4e80 100644
              self.repos.callback = prerepoconf.callback
              self.repos.setFailureCallback(prerepoconf.failure_callback)
              self.repos.setInterruptCallback(prerepoconf.interrupt_callback)
-@@ -602,24 +725,6 @@ class YumBase(depsolve.Depsolve):
+@@ -602,24 +738,6 @@ class YumBase(depsolve.Depsolve):
  
  
          if doSetup:
@@ -191941,7 +192031,7 @@ index 99039e0..a8a4e80 100644
              repo_st = time.time()        
              self._repos.doSetup(thisrepo)
              self.verbose_logger.debug('repo time: %0.3f' % (time.time() - repo_st))        
-@@ -630,6 +735,14 @@ class YumBase(depsolve.Depsolve):
+@@ -630,6 +748,14 @@ class YumBase(depsolve.Depsolve):
          self._repos = RepoStorage(self)
      
      def doSackSetup(self, archlist=None, thisrepo=None):
@@ -191956,7 +192046,7 @@ index 99039e0..a8a4e80 100644
          warnings.warn(_('doSackSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -711,6 +824,9 @@ class YumBase(depsolve.Depsolve):
+@@ -711,6 +837,9 @@ class YumBase(depsolve.Depsolve):
              
             
      def doUpdateSetup(self):
@@ -191966,7 +192056,7 @@ index 99039e0..a8a4e80 100644
          warnings.warn(_('doUpdateSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -765,6 +881,8 @@ class YumBase(depsolve.Depsolve):
+@@ -765,6 +894,8 @@ class YumBase(depsolve.Depsolve):
          return self._up
      
      def doGroupSetup(self):
@@ -191975,7 +192065,7 @@ index 99039e0..a8a4e80 100644
          warnings.warn(_('doGroupSetup() will go away in a future version of Yum.\n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)
  
-@@ -776,7 +894,12 @@ class YumBase(depsolve.Depsolve):
+@@ -776,7 +907,12 @@ class YumBase(depsolve.Depsolve):
              # if we unset the comps object, we need to undo which repos have
              # been added to the group file as well
              if self._repos:
@@ -191989,7 +192079,7 @@ index 99039e0..a8a4e80 100644
                      repo.groups_added = False
          self._comps = val
      
-@@ -801,7 +924,8 @@ class YumBase(depsolve.Depsolve):
+@@ -801,7 +937,8 @@ class YumBase(depsolve.Depsolve):
                  continue
                  
              if not repo.ready():
@@ -191999,7 +192089,7 @@ index 99039e0..a8a4e80 100644
              try:
                  groupremote = repo.getGroupLocation()
              except Errors.RepoMDError, e:
-@@ -813,6 +937,21 @@ class YumBase(depsolve.Depsolve):
+@@ -813,6 +950,21 @@ class YumBase(depsolve.Depsolve):
          overwrite = self.conf.overwrite_groups
          self._comps = comps.Comps(overwrite_groups = overwrite)
  
@@ -192021,7 +192111,7 @@ index 99039e0..a8a4e80 100644
          for repo in reposWithGroups:
              if repo.groups_added: # already added the groups from this repo
                  continue
-@@ -820,16 +959,14 @@ class YumBase(depsolve.Depsolve):
+@@ -820,16 +972,14 @@ class YumBase(depsolve.Depsolve):
              self.verbose_logger.log(logginglevels.DEBUG_4,
                  _('Adding group file from repository: %s'), repo)
              groupfile = repo.getGroups()
@@ -192043,7 +192133,7 @@ index 99039e0..a8a4e80 100644
                  self.logger.critical(msg)
              else:
                  repo.groups_added = True
-@@ -837,7 +974,10 @@ class YumBase(depsolve.Depsolve):
+@@ -837,7 +987,10 @@ class YumBase(depsolve.Depsolve):
          if self._comps.compscount == 0:
              raise Errors.GroupsError, _('No Groups Available in any repository')
  
@@ -192055,7 +192145,7 @@ index 99039e0..a8a4e80 100644
          self.verbose_logger.debug('group time: %0.3f' % (time.time() - group_st))                
          return self._comps
  
-@@ -868,22 +1008,72 @@ class YumBase(depsolve.Depsolve):
+@@ -868,22 +1021,72 @@ class YumBase(depsolve.Depsolve):
                      # feed it into _tags.add()
                      self._tags.add(repo.id, tag_sqlite)
                  except (Errors.RepoError, Errors.PkgTagsError), e:
@@ -192130,7 +192220,7 @@ index 99039e0..a8a4e80 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,16 +1111,31 @@ class YumBase(depsolve.Depsolve):
+@@ -921,16 +1124,31 @@ class YumBase(depsolve.Depsolve):
                         fdel=lambda self: setattr(self, "_history", None),
                         doc="Yum History Object")
  
@@ -192166,7 +192256,7 @@ index 99039e0..a8a4e80 100644
          necessary = False
          
          # I can't think of a nice way of doing this, we have to have the sack here
-@@ -951,25 +1156,37 @@ class YumBase(depsolve.Depsolve):
+@@ -951,25 +1169,37 @@ class YumBase(depsolve.Depsolve):
              self.repos.populateSack(mdtype='filelists')
             
      def yumUtilsMsg(self, func, prog):
@@ -192215,7 +192305,7 @@ index 99039e0..a8a4e80 100644
              self.logger.critical(msg)
              self.yumUtilsMsg(self.logger.critical, "yum-complete-transaction")
              time.sleep(3)
-@@ -1004,7 +1221,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1004,7 +1234,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 )
  
@@ -192224,7 +192314,7 @@ index 99039e0..a8a4e80 100644
              self.tsInfo.pkgSack.dropCachedData()
  
          # FIXME: This is horrible, see below and yummain. Maybe create a real
-@@ -1044,6 +1261,39 @@ class YumBase(depsolve.Depsolve):
+@@ -1044,6 +1274,39 @@ class YumBase(depsolve.Depsolve):
                  if first.verEQ(other):
                      continue
                  msg = _('Protected multilib versions: %s != %s')
@@ -192264,7 +192354,7 @@ index 99039e0..a8a4e80 100644
                  xrestring.append(msg % (first, other))
          if xrestring:
              rescode = 1
-@@ -1227,7 +1477,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1227,7 +1490,7 @@ class YumBase(depsolve.Depsolve):
                  self.verbose_logger.info(msg)
              self.skipped_packages.extend(skipped_list)   # make the skipped packages public
          else:
@@ -192273,7 +192363,7 @@ index 99039e0..a8a4e80 100644
              self.verbose_logger.info("Skip-broken could not solve problems")
              return 1, orig_restring
          return rescode, restring
-@@ -1242,13 +1492,15 @@ class YumBase(depsolve.Depsolve):
+@@ -1242,13 +1505,15 @@ class YumBase(depsolve.Depsolve):
          if None in pkgtup:
              return None
          return pkgtup
@@ -192293,7 +192383,7 @@ index 99039e0..a8a4e80 100644
          if pkgtup is None:
              return
          self._not_found_i[pkgtup] = YumNotFoundPackage(pkgtup)
-@@ -1267,7 +1519,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1267,7 +1532,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
@@ -192302,7 +192392,7 @@ index 99039e0..a8a4e80 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)
-@@ -1275,14 +1527,14 @@ class YumBase(depsolve.Depsolve):
+@@ -1275,14 +1540,14 @@ class YumBase(depsolve.Depsolve):
      def _checkUpdatedLeftovers(self):
          """ 
          If multiple packages is updated the same package
@@ -192319,7 +192409,7 @@ index 99039e0..a8a4e80 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 +1631,19 @@ class YumBase(depsolve.Depsolve):
+@@ -1379,9 +1644,19 @@ class YumBase(depsolve.Depsolve):
  
      def _getDepsToRemove(self,po, deptree, toRemove):
          for dep in deptree.get(po, []): # Loop trough all deps of po
@@ -192339,7 +192429,7 @@ index 99039e0..a8a4e80 100644
              toRemove.add(dep)
              self._getDepsToRemove(dep, deptree, toRemove)
  
-@@ -1454,7 +1716,46 @@ class YumBase(depsolve.Depsolve):
+@@ -1454,7 +1729,66 @@ class YumBase(depsolve.Depsolve):
          return probs
  
      def runTransaction(self, cb):
@@ -192352,6 +192442,13 @@ index 99039e0..a8a4e80 100644
 +        :raises: :class:`yum.Errors.YumRPMTransError` if there is a
 +           transaction cannot be completed
 +        """
++        if (self.conf.fssnap_automatic_pre or self.conf.fssnap_automatic_post) and not self.fssnap.available:
++            msg = _("Snapshot support not available.")
++            if self.conf.fssnap_abort_on_errors in ('broken-setup', 'any'):
++                raise Errors.YumRPMTransError(msg="Aborting transaction.", errors=msg)
++            else:
++                self.verbose_logger.critical(msg)
++
 +        if self.fssnap.available and ((self.conf.fssnap_automatic_pre or
 +                                       self.conf.fssnap_automatic_post) and
 +                                      self.conf.fssnap_automatic_keep):
@@ -192373,21 +192470,34 @@ index 99039e0..a8a4e80 100644
 +                if num > self.conf.fssnap_automatic_keep:
 +                    todel.append(snap['dev'])
 +            # Display something to the user?
-+            self.fssnap.del_snapshots(devices=todel)
++            snaps = self.fssnap.del_snapshots(devices=todel)
++            if len(snaps):
++                self.verbose_logger.info(_("Deleted %u snapshots.") % len(snaps))
 +
 +        if (self.fssnap.available and
 +            (not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
 +            self.conf.fssnap_automatic_pre)):
 +            if not self.fssnap.has_space(self.conf.fssnap_percentage):
-+                msg = _("Not enough space to create pre. FS snapshot, aborting transaction.")
-+                raise Errors.YumRPMTransError(msg=msg, errors=[])
++                msg = _("Not enough space to create pre. FS snapshot.")
++                if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
++                    raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
++                else:
++                    self.verbose_logger.critical(msg)
 +            else:
 +                tags = {'*': ['reason=automatic']} # FIXME: pre. tags
-+                self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
++                snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
++                if not snaps:
++                    msg = _("Failed to create snapshot")
++                    if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
++                        raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
++                    else:
++                        self.verbose_logger.critical(msg)
++                for (odev, ndev) in snaps:
++                    self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
  
          self.plugins.run('pretrans')
  
-@@ -1516,10 +1817,23 @@ class YumBase(depsolve.Depsolve):
+@@ -1516,10 +1850,23 @@ class YumBase(depsolve.Depsolve):
                  pass
          self._ts_save_file = None
          
@@ -192411,7 +192521,7 @@ index 99039e0..a8a4e80 100644
          
          # make resultobject - just a plain yumgenericholder object
          resultobject = misc.GenericHolder()
-@@ -1544,8 +1858,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1544,8 +1891,7 @@ class YumBase(depsolve.Depsolve):
                                            errors=errors)
  
                            
@@ -192421,7 +192531,7 @@ index 99039e0..a8a4e80 100644
              self.cleanUsedHeadersPackages()
          
          for i in ('ts_all_fn', 'ts_done_fn'):
-@@ -1567,13 +1880,35 @@ class YumBase(depsolve.Depsolve):
+@@ -1567,13 +1913,38 @@ 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):
@@ -192438,11 +192548,14 @@ index 99039e0..a8a4e80 100644
 +            self.conf.fssnap_automatic_post)):
 +            if not self.fssnap.has_space(self.conf.fssnap_percentage):
 +                msg = _("Not enough space to create post trans FS snapshot.")
-+                self.logger.critical(msg)
++                self.verbose_logger.critical(msg)
 +            else:
 +                tags = {'*': ['reason=automatic']} # FIXME: post tags
-+                self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
-+
++                snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
++                if not snaps:
++                    self.verbose_logger.critical(_("Failed to create snapshot"))
++                for (odev, ndev) in snaps:
++                    self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
          return resultobject
  
 -    def verifyTransaction(self, resultobject=None):
@@ -192462,7 +192575,7 @@ index 99039e0..a8a4e80 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,24 +1919,58 @@ class YumBase(depsolve.Depsolve):
+@@ -1584,24 +1955,58 @@ 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
@@ -192523,7 +192636,7 @@ index 99039e0..a8a4e80 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 +1999,10 @@ class YumBase(depsolve.Depsolve):
+@@ -1630,6 +2035,10 @@ class YumBase(depsolve.Depsolve):
                      if md:
                          po.yumdb_info.from_repo_timestamp = str(md.timestamp)
  
@@ -192534,7 +192647,7 @@ index 99039e0..a8a4e80 100644
                  loginuid = misc.getloginuid()
                  if txmbr.updates or txmbr.downgrades or txmbr.reinstall:
                      if txmbr.updates:
-@@ -1640,11 +2013,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1640,11 +2049,16 @@ class YumBase(depsolve.Depsolve):
                          opo = po
                      if 'installed_by' in opo.yumdb_info:
                          po.yumdb_info.installed_by = opo.yumdb_info.installed_by
@@ -192551,7 +192664,7 @@ index 99039e0..a8a4e80 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 +2040,13 @@ class YumBase(depsolve.Depsolve):
+@@ -1662,10 +2076,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
@@ -192565,7 +192678,7 @@ index 99039e0..a8a4e80 100644
                  self.verbose_logger.log(logginglevels.DEBUG_2, 'What is this? %s' % txmbr.po)
  
          self.plugins.run('postverifytrans')
-@@ -1680,10 +2061,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1680,10 +2097,11 @@ class YumBase(depsolve.Depsolve):
          self.verbose_logger.debug('VerifyTransaction time: %0.3f' % (time.time() - vt_st))
  
      def costExcludePackages(self):
@@ -192581,7 +192694,7 @@ index 99039e0..a8a4e80 100644
          # if all the repo.costs are equal then don't bother running things
          costs = {}
          for r in self.repos.listEnabled():
-@@ -1705,10 +2087,12 @@ class YumBase(depsolve.Depsolve):
+@@ -1705,10 +2123,12 @@ class YumBase(depsolve.Depsolve):
              done = True
  
      def excludePackages(self, repo=None):
@@ -192597,7 +192710,7 @@ index 99039e0..a8a4e80 100644
          if "all" in self.conf.disable_excludes:
              return
          
-@@ -1735,9 +2119,14 @@ class YumBase(depsolve.Depsolve):
+@@ -1735,9 +2155,14 @@ class YumBase(depsolve.Depsolve):
              self.pkgSack.addPackageExcluder(repoid, exid,'exclude.match', match)
  
      def includePackages(self, repo):
@@ -192615,7 +192728,7 @@ index 99039e0..a8a4e80 100644
          includelist = repo.getIncludePkgList()
          
          if len(includelist) == 0:
-@@ -1757,8 +2146,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1757,8 +2182,11 @@ class YumBase(depsolve.Depsolve):
          self.pkgSack.addPackageExcluder(repo.id, exid, 'exclude.marked')
          
      def doLock(self, lockfile = YUM_PID_FILE):
@@ -192629,7 +192742,7 @@ index 99039e0..a8a4e80 100644
          if self.conf.uid != 0:
              #  If we are a user, assume we are using the root cache ... so don't
              # bother locking.
-@@ -1773,39 +2165,39 @@ class YumBase(depsolve.Depsolve):
+@@ -1773,39 +2201,39 @@ class YumBase(depsolve.Depsolve):
          lockfile = os.path.normpath(lockfile) # get rid of silly preceding extra /
          
          mypid=str(os.getpid())    
@@ -192697,7 +192810,7 @@ index 99039e0..a8a4e80 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 +2222,74 @@ class YumBase(depsolve.Depsolve):
+@@ -1830,31 +2258,74 @@ class YumBase(depsolve.Depsolve):
          self._unlock(lockfile)
          self._lockfile = None
          
@@ -192784,7 +192897,7 @@ index 99039e0..a8a4e80 100644
          failed = False
  
          if type(fo) is types.InstanceType:
-@@ -1877,14 +2312,14 @@ class YumBase(depsolve.Depsolve):
+@@ -1877,14 +2348,14 @@ class YumBase(depsolve.Depsolve):
              cursize = os.stat(fo)[6]
              totsize = long(po.size)
              if cursize >= totsize and not po.repo.cache:
@@ -192803,7 +192916,7 @@ index 99039e0..a8a4e80 100644
                  raise URLGrabError(-1, msg)
              else:
                  return False
-@@ -1894,9 +2329,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1894,9 +2365,16 @@ class YumBase(depsolve.Depsolve):
          
          
      def verifyChecksum(self, fo, checksumType, csum):
@@ -192823,7 +192936,7 @@ index 99039e0..a8a4e80 100644
          try:
              filesum = misc.checksum(checksumType, fo)
          except Errors.MiscError, e:
-@@ -1908,13 +2350,26 @@ class YumBase(depsolve.Depsolve):
+@@ -1908,13 +2386,26 @@ class YumBase(depsolve.Depsolve):
          return 0
  
      def downloadPkgs(self, pkglist, callback=None, callback_total=None):
@@ -192851,7 +192964,7 @@ index 99039e0..a8a4e80 100644
              if a is None:
                  return -1
              if b is None:
-@@ -1925,12 +2380,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1925,12 +2416,11 @@ class YumBase(depsolve.Depsolve):
                  return 1
              return 0
          
@@ -192866,7 +192979,7 @@ index 99039e0..a8a4e80 100644
  
          #  We close the history DB here because some plugins (presto) use
          # threads. And sqlite really doesn't like threads. And while I don't
-@@ -1943,116 +2397,215 @@ class YumBase(depsolve.Depsolve):
+@@ -1943,116 +2433,215 @@ class YumBase(depsolve.Depsolve):
          self.history.close()
  
          self.plugins.run('predownload', pkglist=pkglist)
@@ -193171,7 +193284,7 @@ index 99039e0..a8a4e80 100644
          if type(fo) is types.InstanceType:
              fo = fo.filename
              
-@@ -2076,9 +2629,12 @@ class YumBase(depsolve.Depsolve):
+@@ -2076,9 +2665,12 @@ class YumBase(depsolve.Depsolve):
          return 1
          
      def downloadHeader(self, po):
@@ -193186,7 +193299,7 @@ index 99039e0..a8a4e80 100644
          if hasattr(po, 'pkgtype') and po.pkgtype == 'local':
              return
                  
-@@ -2097,8 +2653,8 @@ class YumBase(depsolve.Depsolve):
+@@ -2097,8 +2689,8 @@ class YumBase(depsolve.Depsolve):
                  return
          else:
              if self.conf.cache:
@@ -193197,7 +193310,7 @@ index 99039e0..a8a4e80 100644
          
          if self.dsCallback: self.dsCallback.downloadHeader(po.name)
          
-@@ -2122,15 +2678,17 @@ class YumBase(depsolve.Depsolve):
+@@ -2122,15 +2714,17 @@ class YumBase(depsolve.Depsolve):
              return
  
      def sigCheckPkg(self, po):
@@ -193223,7 +193336,7 @@ index 99039e0..a8a4e80 100644
          if self._override_sigchecks:
              check = False
              hasgpgkey = 0
-@@ -2181,6 +2739,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2181,6 +2775,9 @@ class YumBase(depsolve.Depsolve):
          return result, msg
  
      def cleanUsedHeadersPackages(self):
@@ -193233,7 +193346,7 @@ index 99039e0..a8a4e80 100644
          filelist = []
          for txmbr in self.tsInfo:
              if txmbr.po.state not in TS_INSTALL_STATES:
-@@ -2189,6 +2750,8 @@ class YumBase(depsolve.Depsolve):
+@@ -2189,6 +2786,8 @@ class YumBase(depsolve.Depsolve):
                  continue
              if txmbr.po.repoid not in self.repos.repos:
                  continue
@@ -193242,7 +193355,7 @@ index 99039e0..a8a4e80 100644
              
              # make sure it's not a local file
              repo = self.repos.repos[txmbr.po.repoid]
-@@ -2218,27 +2781,42 @@ class YumBase(depsolve.Depsolve):
+@@ -2218,27 +2817,42 @@ class YumBase(depsolve.Depsolve):
                      _('%s removed'), fn)
          
      def cleanHeaders(self):
@@ -193287,7 +193400,7 @@ index 99039e0..a8a4e80 100644
          cachedir = self.conf.persistdir + "/rpmdb-indexes/"
          if not os.path.exists(cachedir):
              filelist = []
-@@ -2271,9 +2849,31 @@ class YumBase(depsolve.Depsolve):
+@@ -2271,9 +2885,31 @@ class YumBase(depsolve.Depsolve):
          return 0, [msg]
  
      def doPackageLists(self, pkgnarrow='all', patterns=None, showdups=None,
@@ -193322,7 +193435,7 @@ index 99039e0..a8a4e80 100644
          if showdups is None:
              showdups = self.conf.showdupesfromrepos
          ygh = misc.GenericHolder(iter=pkgnarrow)
-@@ -2295,6 +2895,8 @@ class YumBase(depsolve.Depsolve):
+@@ -2295,6 +2931,8 @@ class YumBase(depsolve.Depsolve):
              ndinst = {} # Newest versions by name.arch
              for po in self.rpmdb.returnPackages(patterns=patterns,
                                                  ignore_case=ic):
@@ -193331,7 +193444,7 @@ index 99039e0..a8a4e80 100644
                  dinst[po.pkgtup] = po
                  if showdups:
                      continue
-@@ -2304,8 +2906,13 @@ class YumBase(depsolve.Depsolve):
+@@ -2304,8 +2942,13 @@ class YumBase(depsolve.Depsolve):
              installed = dinst.values()
                          
              if showdups:
@@ -193346,7 +193459,7 @@ index 99039e0..a8a4e80 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2323,16 +2930,31 @@ class YumBase(depsolve.Depsolve):
+@@ -2323,16 +2966,31 @@ class YumBase(depsolve.Depsolve):
                      key = (pkg.name, pkg.arch)
                      if pkg.pkgtup in dinst:
                          reinstall_available.append(pkg)
@@ -193381,7 +193494,7 @@ index 99039e0..a8a4e80 100644
                  if len(matches) > 1:
                      updates.append(matches[0])
                      self.verbose_logger.log(logginglevels.DEBUG_1,
-@@ -2352,13 +2974,19 @@ class YumBase(depsolve.Depsolve):
+@@ -2352,13 +3010,19 @@ class YumBase(depsolve.Depsolve):
          elif pkgnarrow == 'installed':
              installed = self.rpmdb.returnPackages(patterns=patterns,
                                                    ignore_case=ic)
@@ -193402,7 +193515,7 @@ index 99039e0..a8a4e80 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2392,9 +3020,21 @@ class YumBase(depsolve.Depsolve):
+@@ -2392,9 +3056,21 @@ class YumBase(depsolve.Depsolve):
              avail = set(avail)
              for po in self.rpmdb.returnPackages(patterns=patterns,
                                                  ignore_case=ic):
@@ -193424,7 +193537,7 @@ index 99039e0..a8a4e80 100644
          # obsoleting packages (and what they obsolete)
          elif pkgnarrow == 'obsoletes':
              self.conf.obsoletes = 1
-@@ -2402,6 +3042,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2402,6 +3078,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)
@@ -193432,7 +193545,7 @@ index 99039e0..a8a4e80 100644
                  instpo = self.getInstalledPackageObject(instTup)
                  for po in pkgs:
                      obsoletes.append(po)
-@@ -2433,7 +3074,12 @@ class YumBase(depsolve.Depsolve):
+@@ -2433,7 +3110,12 @@ class YumBase(depsolve.Depsolve):
              recentlimit = now-(self.conf.recent*86400)
              if showdups:
                  avail = self.pkgSack.returnPackages(patterns=patterns,
@@ -193446,7 +193559,7 @@ index 99039e0..a8a4e80 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2461,14 +3107,13 @@ class YumBase(depsolve.Depsolve):
+@@ -2461,14 +3143,13 @@ class YumBase(depsolve.Depsolve):
  
          
      def findDeps(self, pkgs):
@@ -193466,7 +193579,7 @@ index 99039e0..a8a4e80 100644
          results = {}
  
          for pkg in pkgs:
-@@ -2495,10 +3140,22 @@ class YumBase(depsolve.Depsolve):
+@@ -2495,10 +3176,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):
@@ -193493,7 +193606,7 @@ index 99039e0..a8a4e80 100644
          sql_fields = []
          for f in fields:
              sql_fields.append(RPM_TO_SQLITE.get(f, f))
-@@ -2614,7 +3271,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2614,7 +3307,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.
@@ -193502,7 +193615,7 @@ index 99039e0..a8a4e80 100644
          # either, so it's pretty thankless. HTH. HAND.
          # By default just sort using package sorting
          sort_func = operator.itemgetter(0)
-@@ -2661,6 +3318,14 @@ class YumBase(depsolve.Depsolve):
+@@ -2661,6 +3354,14 @@ class YumBase(depsolve.Depsolve):
                      yield (po, vs)
  
      def searchPackageTags(self, criteria):
@@ -193517,7 +193630,7 @@ index 99039e0..a8a4e80 100644
          results = {} # name = [(criteria, taglist)]
          for c in criteria:
              c = c.lower()
-@@ -2677,11 +3342,16 @@ class YumBase(depsolve.Depsolve):
+@@ -2677,11 +3378,16 @@ class YumBase(depsolve.Depsolve):
          return results
          
      def searchPackages(self, fields, criteria, callback=None):
@@ -193539,7 +193652,7 @@ index 99039e0..a8a4e80 100644
          warnings.warn(_('searchPackages() will go away in a future version of Yum.\
                        Use searchGenerator() instead. \n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)           
-@@ -2700,13 +3370,23 @@ class YumBase(depsolve.Depsolve):
+@@ -2700,13 +3406,23 @@ class YumBase(depsolve.Depsolve):
      
      def searchPackageProvides(self, args, callback=None,
                                callback_has_matchfor=False):
@@ -193567,7 +193680,7 @@ index 99039e0..a8a4e80 100644
              else:
                  isglob = True
                  canBeFile = misc.re_filename(arg)
-@@ -2723,7 +3403,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2723,7 +3439,7 @@ class YumBase(depsolve.Depsolve):
                  where = self.returnPackagesByDep(arg)
              else:
                  usedDepString = False
@@ -193576,7 +193689,7 @@ index 99039e0..a8a4e80 100644
              self.verbose_logger.log(logginglevels.DEBUG_1,
                 P_('Searching %d package', 'Searching %d packages', len(where)), len(where))
              
-@@ -2817,29 +3497,170 @@ class YumBase(depsolve.Depsolve):
+@@ -2817,26 +3533,167 @@ class YumBase(depsolve.Depsolve):
              
          return matches
  
@@ -193622,9 +193735,6 @@ index 99039e0..a8a4e80 100644
 -        for grp in grps:
 -            if grp.installed:
 -                if uservisible:
--                    if grp.user_visible:
--                        installed.append(grp)
--                else:
 +            if not ipkgs:
 +                ret[pkg_name] = 'blacklisted-available'
 +                continue
@@ -193763,13 +193873,10 @@ index 99039e0..a8a4e80 100644
 +
 +            if grp_installed:
 +                if uservisible:
-+                    if grp.user_visible:
-+                        installed.append(grp)
-+                else:
-                     installed.append(grp)
-             else:
-                 if uservisible:
-@@ -2847,34 +3668,97 @@ class YumBase(depsolve.Depsolve):
+                     if grp.user_visible:
+                         installed.append(grp)
+                 else:
+@@ -2847,34 +3704,97 @@ class YumBase(depsolve.Depsolve):
                          available.append(grp)
                  else:
                      available.append(grp)
@@ -193875,7 +193982,7 @@ index 99039e0..a8a4e80 100644
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -2898,18 +3782,53 @@ class YumBase(depsolve.Depsolve):
+@@ -2898,18 +3818,53 @@ class YumBase(depsolve.Depsolve):
                              self.tsInfo.remove(txmbr.po.pkgtup)
          
          
@@ -193939,7 +194046,7 @@ index 99039e0..a8a4e80 100644
          txmbrs_used = []
          thesegroups = self.comps.return_groups(grpid)
       
-@@ -2920,12 +3839,18 @@ class YumBase(depsolve.Depsolve):
+@@ -2920,12 +3875,18 @@ class YumBase(depsolve.Depsolve):
          if group_package_types:
              package_types = group_package_types
  
@@ -193958,7 +194065,7 @@ index 99039e0..a8a4e80 100644
              pkgs = []
              if 'mandatory' in package_types:
                  pkgs.extend(thisgroup.mandatory_packages)
-@@ -2934,12 +3859,56 @@ class YumBase(depsolve.Depsolve):
+@@ -2934,12 +3895,56 @@ class YumBase(depsolve.Depsolve):
              if 'optional' in package_types:
                  pkgs.extend(thisgroup.optional_packages)
  
@@ -194016,7 +194123,7 @@ index 99039e0..a8a4e80 100644
                  except Errors.InstallError, e:
                      self.verbose_logger.debug(_('No package named %s available to be installed'),
                          pkg)
-@@ -2953,7 +3922,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2953,7 +3958,9 @@ class YumBase(depsolve.Depsolve):
                  group_conditionals = enable_group_conditionals
  
              count_cond_test = 0
@@ -194027,7 +194134,7 @@ index 99039e0..a8a4e80 100644
                  for condreq, cond in thisgroup.conditional_packages.iteritems():
                      if self.isPackageInstalled(cond):
                          try:
-@@ -2990,17 +3961,23 @@ class YumBase(depsolve.Depsolve):
+@@ -2990,17 +3997,23 @@ class YumBase(depsolve.Depsolve):
                          if cond not in self.tsInfo.conditionals:
                              self.tsInfo.conditionals[cond] = []
                          self.tsInfo.conditionals[cond].extend(pkgs)
@@ -194058,7 +194165,7 @@ index 99039e0..a8a4e80 100644
          
          if not self.comps.has_group(grpid):
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3008,7 +3985,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3008,7 +4021,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)
@@ -194068,7 +194175,7 @@ index 99039e0..a8a4e80 100644
          for thisgroup in thesegroups:
              thisgroup.selected = False
              
-@@ -3034,13 +4012,114 @@ class YumBase(depsolve.Depsolve):
+@@ -3034,13 +4048,114 @@ class YumBase(depsolve.Depsolve):
                          for pkg in self.tsInfo.conditionals.get(txmbr.name, []):
                              self.tsInfo.remove(pkg.pkgtup)
          
@@ -194189,7 +194296,7 @@ index 99039e0..a8a4e80 100644
          # look it up in the self.localPackages first:
          for po in self.localPackages:
              if po.pkgtup == pkgtup:
-@@ -3049,7 +4128,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3049,7 +4164,7 @@ class YumBase(depsolve.Depsolve):
          pkgs = self.pkgSack.searchPkgTuple(pkgtup)
  
          if len(pkgs) == 0:
@@ -194198,7 +194305,7 @@ index 99039e0..a8a4e80 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 +4144,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3065,13 +4180,21 @@ class YumBase(depsolve.Depsolve):
          return result
  
      def getInstalledPackageObject(self, pkgtup):
@@ -194225,7 +194332,7 @@ index 99039e0..a8a4e80 100644
              raise Errors.RpmDBError, _('Package tuple %s could not be found in rpmdb') % str(pkgtup)
  
          # Dito. FIXME from getPackageObject() for len() > 1 ... :)
-@@ -3079,9 +4166,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3079,9 +4202,11 @@ class YumBase(depsolve.Depsolve):
          return po
          
      def gpgKeyCheck(self):
@@ -194239,7 +194346,7 @@ index 99039e0..a8a4e80 100644
          gpgkeyschecked = self.conf.cachedir + '/.gpgkeyschecked.yum'
          if os.path.exists(gpgkeyschecked):
              return 1
-@@ -3106,9 +4195,13 @@ class YumBase(depsolve.Depsolve):
+@@ -3106,9 +4231,13 @@ class YumBase(depsolve.Depsolve):
              return 1
  
      def returnPackagesByDep(self, depstring):
@@ -194255,7 +194362,7 @@ index 99039e0..a8a4e80 100644
          if not depstring:
              return []
  
-@@ -3132,12 +4225,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3132,12 +4261,23 @@ class YumBase(depsolve.Depsolve):
                          raise Errors.YumBaseError, _('Invalid version flag from: %s') % str(depstring)
                      depflags = SYMBOLFLAGS[flagsymbol]
  
@@ -194282,7 +194389,7 @@ index 99039e0..a8a4e80 100644
          # we get all sorts of randomness here
          errstring = depstring
          if type(depstring) not in types.StringTypes:
-@@ -3149,16 +4253,22 @@ class YumBase(depsolve.Depsolve):
+@@ -3149,16 +4289,22 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _('No Package found for %s') % errstring
          
          ps = ListPackageSack(pkglist)
@@ -194309,7 +194416,7 @@ index 99039e0..a8a4e80 100644
          if not depstring:
              return []
  
-@@ -3182,14 +4292,53 @@ class YumBase(depsolve.Depsolve):
+@@ -3182,14 +4328,53 @@ class YumBase(depsolve.Depsolve):
                          raise Errors.YumBaseError, _('Invalid version flag from: %s') % str(depstring)
                      depflags = SYMBOLFLAGS[flagsymbol]
  
@@ -194365,7 +194472,7 @@ index 99039e0..a8a4e80 100644
          
          
          if len(pkglist) == 0:
-@@ -3198,14 +4347,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3198,14 +4383,23 @@ class YumBase(depsolve.Depsolve):
          if len(pkglist) == 1:
              return pkglist[0]
  
@@ -194395,7 +194502,7 @@ index 99039e0..a8a4e80 100644
          returnlist = []
          compatArchList = self.arch.get_arch_list(arch)
          multiLib = []
-@@ -3222,9 +4380,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3222,9 +4416,9 @@ class YumBase(depsolve.Depsolve):
                  singleLib.append(po)
                  
          # we now have three lists.  find the best package(s) of each
@@ -194408,7 +194515,7 @@ index 99039e0..a8a4e80 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 +4396,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3238,7 +4432,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:
@@ -194417,7 +194524,7 @@ index 99039e0..a8a4e80 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3246,7 +4404,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3246,7 +4440,7 @@ class YumBase(depsolve.Depsolve):
                  if single: returnlist.append(single)
          # similar for the non-multilib case
          elif single:
@@ -194426,7 +194533,7 @@ index 99039e0..a8a4e80 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3350,28 +4508,71 @@ class YumBase(depsolve.Depsolve):
+@@ -3350,28 +4544,71 @@ class YumBase(depsolve.Depsolve):
              done = True
  
              slow = next_func(slow)
@@ -194508,7 +194615,7 @@ index 99039e0..a8a4e80 100644
          try:
              txmbrs = self.groupRemove(group_string)
          except yum.Errors.GroupsError:
-@@ -3387,6 +4588,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3387,6 +4624,8 @@ class YumBase(depsolve.Depsolve):
          assert pattern[0] == '@'
          grpid = pattern[1:]
  
@@ -194517,7 +194624,7 @@ index 99039e0..a8a4e80 100644
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3398,7 +4601,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3398,7 +4637,11 @@ class YumBase(depsolve.Depsolve):
      def _minus_deselect(self, pattern):
          """ Remove things from the transaction, like kickstart. """
          assert pattern[0] == '-'
@@ -194530,7 +194637,7 @@ index 99039e0..a8a4e80 100644
  
          if pat and pat[0] == '@':
              pat = pat[1:]
-@@ -3437,14 +4644,87 @@ class YumBase(depsolve.Depsolve):
+@@ -3437,14 +4680,90 @@ class YumBase(depsolve.Depsolve):
              if flag not in self.tsInfo.probFilterFlags:
                  self.tsInfo.probFilterFlags.append(flag)
  
@@ -194544,6 +194651,9 @@ index 99039e0..a8a4e80 100644
 +            # don't have to.
 +            return po.pkgtup in self.up.updating_dict
 +
++        if self.allowedMultipleInstalls(po):
++            return False
++
 +        for ipkg in ipkgs:
 +            if po.verLE(ipkg):
 +                continue
@@ -194624,7 +194734,7 @@ index 99039e0..a8a4e80 100644
          pkgs = []
          was_pattern = False
          if po:
-@@ -3464,9 +4744,14 @@ class YumBase(depsolve.Depsolve):
+@@ -3464,9 +4783,14 @@ class YumBase(depsolve.Depsolve):
                  if kwargs['pattern'] and kwargs['pattern'][0] == '@':
                      return self._at_groupinstall(kwargs['pattern'])
  
@@ -194639,7 +194749,7 @@ index 99039e0..a8a4e80 100644
                                                        ignore_case=False)
                  pkgs.extend(mypkgs)
                  # if we have anything left unmatched, let's take a look for it
-@@ -3477,20 +4762,14 @@ class YumBase(depsolve.Depsolve):
+@@ -3477,20 +4801,14 @@ class YumBase(depsolve.Depsolve):
                      self.verbose_logger.debug(_('Checking for virtual provide or file-provide for %s'), 
                          arg)
  
@@ -194668,7 +194778,7 @@ index 99039e0..a8a4e80 100644
              else:
                  nevra_dict = self._nevra_kwarg_parse(kwargs)
  
-@@ -3499,6 +4778,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3499,6 +4817,8 @@ class YumBase(depsolve.Depsolve):
                       ver=nevra_dict['version'], rel=nevra_dict['release'])
                  self._add_not_found_a(pkgs, nevra_dict)
                  
@@ -194677,7 +194787,7 @@ index 99039e0..a8a4e80 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 +4858,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3577,17 +4897,21 @@ class YumBase(depsolve.Depsolve):
                      continue
              
              # make sure this shouldn't be passed to update:
@@ -194703,7 +194813,7 @@ index 99039e0..a8a4e80 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 +4885,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3600,23 +4924,23 @@ class YumBase(depsolve.Depsolve):
                      already_obs = pkgs[0]
  
                  if already_obs:
@@ -194734,7 +194844,7 @@ index 99039e0..a8a4e80 100644
                      continue
  
              # make sure we don't have a name.arch of this already installed
-@@ -3630,8 +4915,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3630,8 +4954,8 @@ class YumBase(depsolve.Depsolve):
                          found = True
                          break
                  if not found:
@@ -194745,7 +194855,7 @@ index 99039e0..a8a4e80 100644
                      tx_return.extend(txmbrs)
                      continue
  
-@@ -3719,19 +5004,47 @@ class YumBase(depsolve.Depsolve):
+@@ -3719,19 +5043,47 @@ class YumBase(depsolve.Depsolve):
          return txmbr
  
      def update(self, po=None, requiringPo=None, update_to=False, **kwargs):
@@ -194800,7 +194910,7 @@ index 99039e0..a8a4e80 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 +5078,15 @@ class YumBase(depsolve.Depsolve):
+@@ -3765,7 +5117,15 @@ class YumBase(depsolve.Depsolve):
                      if new is None:
                          continue
                      tx_return.extend(self.update(po=new))
@@ -194817,7 +194927,7 @@ index 99039e0..a8a4e80 100644
              return tx_return
  
          # complications
-@@ -3787,13 +5108,16 @@ class YumBase(depsolve.Depsolve):
+@@ -3787,13 +5147,16 @@ class YumBase(depsolve.Depsolve):
                  return self._minus_deselect(kwargs['pattern'])
  
              if kwargs['pattern'] and kwargs['pattern'][0] == '@':
@@ -194836,7 +194946,7 @@ index 99039e0..a8a4e80 100644
  
              if not instpkgs and not availpkgs:
                  depmatches = []
-@@ -3805,6 +5129,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3805,6 +5168,8 @@ class YumBase(depsolve.Depsolve):
                  except yum.Errors.YumBaseError, e:
                      self.logger.critical(_('%s') % e)
  
@@ -194845,7 +194955,7 @@ index 99039e0..a8a4e80 100644
                  if update_to:
                      availpkgs.extend(depmatches)
                  else:
-@@ -3816,9 +5142,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3816,9 +5181,12 @@ class YumBase(depsolve.Depsolve):
              try:
                  if update_to:
                      m = []
@@ -194859,7 +194969,7 @@ index 99039e0..a8a4e80 100644
                      m = self.pkgSack.returnNewestByNameArch(patterns=pats)
              except Errors.PackageSackError:
                  m = []
-@@ -3843,7 +5172,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3843,7 +5211,7 @@ class YumBase(depsolve.Depsolve):
                      availpkgs = self._compare_providers(availpkgs, requiringPo)
                      availpkgs = map(lambda x: x[0], availpkgs)
                  elif not availpkgs:
@@ -194868,7 +194978,7 @@ index 99039e0..a8a4e80 100644
         
          # for any thing specified
          # get the list of available pkgs matching it (or take the po)
-@@ -3879,6 +5208,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3879,6 +5247,7 @@ class YumBase(depsolve.Depsolve):
                      if obsoleting_pkg is None:
                          continue
                      obs_pkgs.append(obsoleting_pkg)
@@ -194876,7 +194986,7 @@ index 99039e0..a8a4e80 100644
                  for obsoleting_pkg in packagesNewestByName(obs_pkgs):
                      tx_return.extend(self.install(po=obsoleting_pkg))
              for available_pkg in availpkgs:
-@@ -3920,11 +5250,29 @@ class YumBase(depsolve.Depsolve):
+@@ -3920,11 +5289,29 @@ class YumBase(depsolve.Depsolve):
                      tx_return.append(txmbr)
                          
          for available_pkg in availpkgs:
@@ -194906,7 +195016,7 @@ index 99039e0..a8a4e80 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 +5333,18 @@ class YumBase(depsolve.Depsolve):
+@@ -3985,11 +5372,18 @@ class YumBase(depsolve.Depsolve):
          return tx_return
          
      def remove(self, po=None, **kwargs):
@@ -194930,7 +195040,7 @@ index 99039e0..a8a4e80 100644
          if not po and not kwargs:
              raise Errors.RemoveError, 'Nothing specified to remove'
          
-@@ -4008,6 +5363,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4008,6 +5402,10 @@ class YumBase(depsolve.Depsolve):
                      return self._at_groupremove(kwargs['pattern'])
  
                  (e,m,u) = self.rpmdb.matchPackageNames([kwargs['pattern']])
@@ -194941,7 +195051,7 @@ index 99039e0..a8a4e80 100644
                  pkgs.extend(e)
                  pkgs.extend(m)
                  if u:
-@@ -4018,6 +5377,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4018,6 +5416,10 @@ class YumBase(depsolve.Depsolve):
                      except yum.Errors.YumBaseError, e:
                          self.logger.critical(_('%s') % e)
                      
@@ -194952,7 +195062,7 @@ index 99039e0..a8a4e80 100644
                      if not depmatches:
                          arg = to_unicode(arg)
                          self.logger.critical(_('No Match for argument: %s') % to_unicode(arg))
-@@ -4055,17 +5418,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4055,17 +5457,19 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def installLocal(self, pkg, po=None, updateonly=False):
@@ -194982,7 +195092,7 @@ index 99039e0..a8a4e80 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 +5548,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4183,16 +5587,15 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def reinstallLocal(self, pkg, po=None):
@@ -195007,7 +195117,7 @@ index 99039e0..a8a4e80 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4215,13 +5579,29 @@ class YumBase(depsolve.Depsolve):
+@@ -4215,13 +5618,29 @@ class YumBase(depsolve.Depsolve):
          return self.reinstall(po=po)
  
      def reinstall(self, po=None, **kwargs):
@@ -195040,7 +195150,7 @@ index 99039e0..a8a4e80 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 +5620,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4240,10 +5659,11 @@ class YumBase(depsolve.Depsolve):
              # pkgs that are obsolete.
              old_conf_obs = self.conf.obsoletes
              self.conf.obsoletes = False
@@ -195054,7 +195164,7 @@ index 99039e0..a8a4e80 100644
              self.conf.obsoletes = old_conf_obs
              if len(members) == 0:
                  self.tsInfo.remove(item.pkgtup)
-@@ -4259,16 +5640,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4259,16 +5679,15 @@ class YumBase(depsolve.Depsolve):
          return tx_mbrs
          
      def downgradeLocal(self, pkg, po=None):
@@ -195079,7 +195189,7 @@ index 99039e0..a8a4e80 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4309,13 +5689,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4309,13 +5728,19 @@ class YumBase(depsolve.Depsolve):
          return False
          
      def downgrade(self, po=None, **kwargs):
@@ -195106,7 +195216,7 @@ index 99039e0..a8a4e80 100644
          if not po and not kwargs:
              raise Errors.DowngradeError, 'Nothing specified to downgrade'
  
-@@ -4397,6 +5783,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4397,6 +5822,10 @@ class YumBase(depsolve.Depsolve):
          # installed version. Indexed fromn the latest installed pkgtup.
          downgrade_apkgs = {}
          for pkg in sorted(apkgs):
@@ -195117,7 +195227,7 @@ index 99039e0..a8a4e80 100644
              na  = (pkg.name, pkg.arch)
  
              # Here we allow downgrades from .i386 => .noarch, or .i586 => .i386
-@@ -4421,6 +5811,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4421,6 +5850,9 @@ class YumBase(depsolve.Depsolve):
                  warned_nas.add(na)
                  continue
  
@@ -195127,7 +195237,7 @@ index 99039e0..a8a4e80 100644
              if pkg.verGE(lipkg):
                  if na not in warned_nas:
                      msg = _('Only Upgrade available on package: %s') % pkg
-@@ -4457,7 +5850,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4457,7 +5889,7 @@ class YumBase(depsolve.Depsolve):
          if e and v and r:
              evr = '%s:%s-%s' % (e, v, r)
          elif v and r:
@@ -195136,7 +195246,7 @@ index 99039e0..a8a4e80 100644
          elif e and v:
              evr = '%s:%s' % (e, v)
          elif v: # e and r etc. is just too weird to print
-@@ -4500,12 +5893,24 @@ class YumBase(depsolve.Depsolve):
+@@ -4500,12 +5932,24 @@ class YumBase(depsolve.Depsolve):
  
          return returndict
  
@@ -195164,7 +195274,7 @@ index 99039e0..a8a4e80 100644
          old_conf_obs = self.conf.obsoletes
          self.conf.obsoletes = False
          done = False
-@@ -4515,19 +5920,46 @@ class YumBase(depsolve.Depsolve):
+@@ -4515,19 +5959,46 @@ class YumBase(depsolve.Depsolve):
                      done = True
          for pkg in transaction.trans_data:
              if pkg.state == 'Downgrade':
@@ -195211,7 +195321,7 @@ index 99039e0..a8a4e80 100644
                  if self.install(pkgtup=pkg.pkgtup):
                      done = True
          for pkg in transaction.trans_data:
-@@ -4538,8 +5970,14 @@ class YumBase(depsolve.Depsolve):
+@@ -4538,8 +6009,14 @@ class YumBase(depsolve.Depsolve):
          return done
  
      def history_undo(self, transaction):
@@ -195228,7 +195338,7 @@ index 99039e0..a8a4e80 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 +6054,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4616,7 +6093,7 @@ class YumBase(depsolve.Depsolve):
  
          except urlgrabber.grabber.URLGrabError, e:
              raise Errors.YumBaseError(_('GPG key retrieval failed: ') +
@@ -195237,7 +195347,7 @@ index 99039e0..a8a4e80 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 +6087,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4649,7 +6126,7 @@ class YumBase(depsolve.Depsolve):
              keys_info = misc.getgpgkeyinfo(rawkey, multiple=True)
          except ValueError, e:
              raise Errors.YumBaseError(_('Invalid GPG Key from %s: %s') % 
@@ -195246,7 +195356,7 @@ index 99039e0..a8a4e80 100644
          keys = []
          for keyinfo in keys_info:
              thiskey = {}
-@@ -4674,39 +6112,49 @@ class YumBase(depsolve.Depsolve):
+@@ -4674,39 +6151,49 @@ class YumBase(depsolve.Depsolve):
              if pkgs:
                  pkgs = sorted(pkgs)[-1]
                  msg = (_('Importing %s key 0x%s:\n'
@@ -195314,7 +195424,7 @@ index 99039e0..a8a4e80 100644
          user_cb_fail = False
          for keyurl in keyurls:
              keys = self._retrievePublicKey(keyurl, repo)
-@@ -4725,7 +6173,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4725,7 +6212,9 @@ class YumBase(depsolve.Depsolve):
                      # Try installing/updating GPG key
                      self._getKeyImportMessage(info, keyurl)
                      rc = False
@@ -195325,7 +195435,7 @@ index 99039e0..a8a4e80 100644
                          rc = True
                          
                      # grab the .sig/.asc for the keyurl, if it exists
-@@ -4751,8 +6201,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4751,8 +6240,8 @@ class YumBase(depsolve.Depsolve):
                  ts = self.rpmdb.readOnlyTS()
                  result = ts.pgpImportPubkey(misc.procgpgkey(info['raw_key']))
                  if result != 0:
@@ -195336,7 +195446,7 @@ index 99039e0..a8a4e80 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
  
-@@ -4760,18 +6210,20 @@ class YumBase(depsolve.Depsolve):
+@@ -4760,18 +6249,20 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _("Didn't install any keys")
  
          if not key_installed:
@@ -195362,7 +195472,7 @@ index 99039e0..a8a4e80 100644
      
      def _getAnyKeyForRepo(self, repo, destdir, keyurl_list, is_cakey=False, callback=None):
          """
-@@ -4788,6 +6240,18 @@ class YumBase(depsolve.Depsolve):
+@@ -4788,6 +6279,18 @@ class YumBase(depsolve.Depsolve):
          """
  
          key_installed = False
@@ -195381,7 +195491,7 @@ index 99039e0..a8a4e80 100644
          user_cb_fail = False
          for keyurl in keyurl_list:
              keys = self._retrievePublicKey(keyurl, repo, getSig=not is_cakey)
-@@ -4819,8 +6283,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4819,8 +6322,11 @@ class YumBase(depsolve.Depsolve):
                  if not key_installed:
                      self._getKeyImportMessage(info, keyurl, keytype)
                      rc = False
@@ -195394,7 +195504,7 @@ index 99039e0..a8a4e80 100644
                      elif callback:
                          rc = callback({"repo": repo, "userid": info['userid'],
                                          "hexkeyid": info['hexkeyid'], "keyurl": keyurl,
-@@ -4835,7 +6302,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4835,7 +6341,8 @@ class YumBase(depsolve.Depsolve):
                  # Import the key
                  result = misc.import_key_to_pubring(info['raw_key'], info['hexkeyid'], gpgdir=destdir)
                  if not result:
@@ -195404,7 +195514,7 @@ index 99039e0..a8a4e80 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
                  # write out the key id to imported_cakeys in the repos basedir
-@@ -4851,36 +6319,35 @@ class YumBase(depsolve.Depsolve):
+@@ -4851,36 +6358,35 @@ class YumBase(depsolve.Depsolve):
                              pass
  
          if not key_installed and user_cb_fail:
@@ -195457,7 +195567,7 @@ index 99039e0..a8a4e80 100644
          self._getAnyKeyForRepo(repo, repo.gpgcadir, repo.gpgcakey, is_cakey=True, callback=callback)
  
      def _limit_installonly_pkgs(self):
-@@ -4889,7 +6356,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4889,7 +6395,7 @@ class YumBase(depsolve.Depsolve):
              New in 3.2.24: Obey yumdb_info.installonly data. """
  
          def _sort_and_filter_installonly(pkgs):
@@ -195466,7 +195576,7 @@ index 99039e0..a8a4e80 100644
                  using the yumdb. """
              ret_beg = []
              ret_mid = []
-@@ -4917,6 +6384,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4917,6 +6423,10 @@ class YumBase(depsolve.Depsolve):
  
          if self.conf.installonly_limit < 1 :
              return 
@@ -195477,7 +195587,7 @@ index 99039e0..a8a4e80 100644
              
          toremove = []
          #  We "probably" want to use either self.ts or self.rpmdb.ts if either
-@@ -4926,23 +6397,30 @@ class YumBase(depsolve.Depsolve):
+@@ -4926,23 +6436,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)
@@ -195516,7 +195626,7 @@ index 99039e0..a8a4e80 100644
              for po in installed:
                  if (po.version, po.release) == (cur_kernel_v, cur_kernel_r): 
                      # don't remove running
-@@ -4959,19 +6437,22 @@ class YumBase(depsolve.Depsolve):
+@@ -4959,19 +6476,22 @@ class YumBase(depsolve.Depsolve):
              txmbr.depends_on.append(rel)
  
      def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None):
@@ -195552,7 +195662,7 @@ index 99039e0..a8a4e80 100644
          
          if not callback:
              callback = callbacks.ProcessTransNoOutputCallback()
-@@ -5062,8 +6543,8 @@ class YumBase(depsolve.Depsolve):
+@@ -5062,8 +6582,8 @@ class YumBase(depsolve.Depsolve):
                  raise Errors.YumRPMCheckError, retmsgs
              retmsgs = [_('ERROR with transaction check vs depsolve:')]
              retmsgs.extend(msgs) 
@@ -195563,7 +195673,7 @@ index 99039e0..a8a4e80 100644
              raise Errors.YumRPMCheckError,retmsgs
          
          tsConf = {}
-@@ -5114,13 +6595,19 @@ class YumBase(depsolve.Depsolve):
+@@ -5114,13 +6634,19 @@ class YumBase(depsolve.Depsolve):
          return results
  
      def add_enable_repo(self, repoid, baseurls=[], mirrorlist=None, **kwargs):
@@ -195590,7 +195700,7 @@ index 99039e0..a8a4e80 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 +6654,15 @@ class YumBase(depsolve.Depsolve):
+@@ -5167,9 +6693,15 @@ class YumBase(depsolve.Depsolve):
  
      def setCacheDir(self, force=False, tmpdir=None, reuse=True,
                      suffix='/$basearch/$releasever'):
@@ -195609,7 +195719,7 @@ index 99039e0..a8a4e80 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 +6672,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5179,7 +6711,7 @@ class YumBase(depsolve.Depsolve):
          try:
              cachedir = misc.getCacheDir(tmpdir, reuse)
          except (IOError, OSError), e:
@@ -195618,7 +195728,7 @@ index 99039e0..a8a4e80 100644
              cachedir = None
              
          if cachedir is None:
-@@ -5190,6 +6683,8 @@ class YumBase(depsolve.Depsolve):
+@@ -5190,6 +6722,8 @@ class YumBase(depsolve.Depsolve):
              self.prerepoconf.cachedir = cachedir
          else:
              self.repos.setCacheDir(cachedir)
@@ -195627,7 +195737,7 @@ index 99039e0..a8a4e80 100644
          self.conf.cachedir = cachedir
          return True # We got a new cache dir
  
-@@ -5220,13 +6715,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5220,13 +6754,24 @@ class YumBase(depsolve.Depsolve):
          self.history.write_addon_data('config-repos', myrepos)
          
      def verify_plugins_cb(self, verify_package):
@@ -195655,7 +195765,7 @@ index 99039e0..a8a4e80 100644
          if self.tsInfo._unresolvedMembers:
              if auto:
                  self.logger.critical(_("Dependencies not solved. Will not save unresolved transaction."))
-@@ -5234,7 +6740,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5234,7 +6779,7 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError(_("Dependencies not solved. Will not save unresolved transaction."))
          
          if not filename:
@@ -195664,7 +195774,7 @@ index 99039e0..a8a4e80 100644
              fd,filename = tempfile.mkstemp(suffix='.yumtx', prefix=prefix)
              f = os.fdopen(fd, 'w')
          else:
-@@ -5244,13 +6750,17 @@ class YumBase(depsolve.Depsolve):
+@@ -5244,13 +6789,17 @@ class YumBase(depsolve.Depsolve):
          
          msg = "%s\n" % self.rpmdb.simpleVersion(main_only=True)[0]
          msg += "%s\n" % self.ts.getTsFlags()
@@ -195685,7 +195795,7 @@ index 99039e0..a8a4e80 100644
          msg += "%s\n" % len(self.tsInfo.getMembers())
          for txmbr in self.tsInfo.getMembers():
              msg += txmbr._dump()
-@@ -5260,42 +6770,84 @@ class YumBase(depsolve.Depsolve):
+@@ -5260,42 +6809,84 @@ class YumBase(depsolve.Depsolve):
          except (IOError, OSError), e:
              self._ts_save_file = None
              if auto:
@@ -195782,7 +195892,7 @@ index 99039e0..a8a4e80 100644
              if ignorerpm:
                  msg += _(" ignoring, as requested.")
                  self.logger.critical(_(msg))
-@@ -5318,8 +6870,17 @@ class YumBase(depsolve.Depsolve):
+@@ -5318,8 +6909,17 @@ class YumBase(depsolve.Depsolve):
          numrepos = int(data[2].strip())
          repos = []
          rindex=3+numrepos
@@ -195801,7 +195911,7 @@ index 99039e0..a8a4e80 100644
  
          # pkgs/txmbrs
          numpkgs = int(data[rindex].strip())
-@@ -5329,6 +6890,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5329,6 +6929,7 @@ class YumBase(depsolve.Depsolve):
          pkgcount = 0
          pkgprob = False
          curpkg = None
@@ -195809,7 +195919,7 @@ index 99039e0..a8a4e80 100644
          for l in data[pkgstart:]:
              l = l.rstrip()
              # our main txmbrs
-@@ -5356,6 +6918,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5356,6 +6957,7 @@ class YumBase(depsolve.Depsolve):
                      if not ignoremissing:
                          raise Errors.YumBaseError(msg)
                      else:
@@ -195817,7 +195927,7 @@ index 99039e0..a8a4e80 100644
                          self.logger.critical(msg)
                  else:
                      pkgcount += 1
-@@ -5432,12 +6995,18 @@ class YumBase(depsolve.Depsolve):
+@@ -5432,12 +7034,18 @@ class YumBase(depsolve.Depsolve):
          if pkgprob:
              msg = _("Transaction members, relations are missing or ts has been modified,")
              if ignoremissing:
@@ -195836,7 +195946,7 @@ index 99039e0..a8a4e80 100644
          return self.tsInfo.getMembers()
  
      def _remove_old_deps(self):
-@@ -5470,18 +7039,6 @@ class YumBase(depsolve.Depsolve):
+@@ -5470,18 +7078,6 @@ class YumBase(depsolve.Depsolve):
                      if requiring == required: # if they are self-requiring skip them
                          continue
                          
@@ -195855,7 +195965,7 @@ index 99039e0..a8a4e80 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 +7090,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5533,7 +7129,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
@@ -195880,7 +195990,7 @@ index 99039e0..a8a4e80 100644
                  visited[curpkg] = True
              all_leaves_visited = True
              leaves = curpkg.requiring_packages()
-@@ -5547,4 +7121,3 @@ class YumBase(depsolve.Depsolve):
+@@ -5547,4 +7160,3 @@ class YumBase(depsolve.Depsolve):
          # Debugging output
          self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has no user-installed revdeps."), pkg)
          return False
@@ -196554,7 +196664,7 @@ index 65f6d5e..92e87ba 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..8eab5bc 100644
+index d09511f..fc1bdc4 100644
 --- a/yum/config.py
 +++ b/yum/config.py
 @@ -38,22 +38,30 @@ if not _use_iniparse:
@@ -197260,7 +197370,7 @@ index d09511f..8eab5bc 100644
      installroot = Option('/')
      config_file_path = Option('/etc/yum/yum.conf')
      plugins = BoolOption(False)
-@@ -625,13 +731,13 @@ class StartupConf(BaseConfig):
+@@ -625,15 +731,16 @@ class StartupConf(BaseConfig):
      persistdir = Option('/var/lib/yum')
      
  class YumConf(StartupConf):
@@ -197277,8 +197387,11 @@ index d09511f..8eab5bc 100644
 +    reset_nice = BoolOption(True)
  
      cachedir = Option('/var/cache/yum')
++    cashedir = Option('/var/cache/CAShe')
  
-@@ -641,29 +747,33 @@ class YumConf(StartupConf):
+     keepcache = BoolOption(True)
+     logfile = Option('/var/log/yum.log')
+@@ -641,29 +748,33 @@ class YumConf(StartupConf):
  
      commands = ListOption()
      exclude = ListOption()
@@ -197322,7 +197435,7 @@ index d09511f..8eab5bc 100644
      alwaysprompt = BoolOption(True)
      exactarch = BoolOption(True)
      tolerant = BoolOption(True)
-@@ -677,18 +787,35 @@ class YumConf(StartupConf):
+@@ -677,33 +788,53 @@ class YumConf(StartupConf):
      obsoletes = BoolOption(True)
      showdupesfromrepos = BoolOption(False)
      enabled = BoolOption(True)
@@ -197358,7 +197471,9 @@ index d09511f..8eab5bc 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
-@@ -697,13 +824,15 @@ class YumConf(StartupConf):
+     rpm_check_debug = BoolOption(True)
+     disable_excludes = ListOption()    
++    query_install_excludes = BoolOption(True)
      skip_broken = BoolOption(False)
      #  Note that "instant" is the old behaviour, but group:primary is very
      # similar but better :).
@@ -197377,7 +197492,7 @@ index d09511f..8eab5bc 100644
  
      color = SelectionOption('auto', ('auto', 'never', 'always'),
                              mapper={'on' : 'always', 'yes' : 'always',
-@@ -715,22 +844,27 @@ class YumConf(StartupConf):
+@@ -715,22 +846,27 @@ class YumConf(StartupConf):
      color_list_installed_newer = Option('bold,yellow')
      color_list_installed_reinstall = Option('normal')
      color_list_installed_extra = Option('bold,red')
@@ -197405,7 +197520,7 @@ index d09511f..8eab5bc 100644
  
      history_record = BoolOption(True)
      history_record_packages = ListOption(['yum', 'rpm'])
-@@ -744,18 +878,45 @@ class YumConf(StartupConf):
+@@ -744,18 +880,46 @@ class YumConf(StartupConf):
      
      loadts_ignoremissing = BoolOption(False)
      loadts_ignorerpm = BoolOption(False)
@@ -197430,6 +197545,7 @@ index d09511f..8eab5bc 100644
 +    fssnap_devices = ListOption("!*/swap !*/lv_swap "
 +                                "glob:/etc/yum/fssnap.d/*.conf",
 +                                parse_default=True)
++    fssnap_abort_on_errors = SelectionOption('any', ('broken-setup', 'snapshot-failure', 'any', 'none'))
 +
 +    depsolve_loop_limit = PositiveIntOption(100, names_of_0=["<forever>"])
 +
@@ -197451,7 +197567,7 @@ index d09511f..8eab5bc 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 +939,12 @@ class YumConf(StartupConf):
+@@ -778,14 +942,12 @@ class YumConf(StartupConf):
          return output
  
  class RepoConf(BaseConfig):
@@ -197469,7 +197585,7 @@ index d09511f..8eab5bc 100644
          ck = self.__cached_keys
          if not isinstance(self, RepoConf):
              ck = set()
-@@ -797,6 +956,7 @@ class RepoConf(BaseConfig):
+@@ -797,6 +959,7 @@ class RepoConf(BaseConfig):
  
      name = Option()
      enabled = Inherit(YumConf.enabled)
@@ -197477,7 +197593,7 @@ index d09511f..8eab5bc 100644
      baseurl = UrlListOption()
      mirrorlist = UrlOption()
      metalink   = UrlOption()
-@@ -820,42 +980,77 @@ class RepoConf(BaseConfig):
+@@ -820,42 +983,77 @@ class RepoConf(BaseConfig):
      keepalive = Inherit(YumConf.keepalive)
      enablegroups = Inherit(YumConf.enablegroups)
  
@@ -197566,7 +197682,7 @@ index d09511f..8eab5bc 100644
  
      # ' xemacs syntax hack
  
-@@ -864,6 +1059,12 @@ def readStartupConfig(configfile, root):
+@@ -864,6 +1062,12 @@ def readStartupConfig(configfile, root):
      startupconf.config_file_path = configfile
      parser = ConfigParser()
      confpp_obj = ConfigPreProcessor(configfile)
@@ -197579,7 +197695,7 @@ index d09511f..8eab5bc 100644
      try:
          parser.readfp(confpp_obj)
      except ParsingError, e:
-@@ -876,25 +1077,29 @@ def readStartupConfig(configfile, root):
+@@ -876,25 +1080,29 @@ 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
@@ -197617,7 +197733,7 @@ index d09511f..8eab5bc 100644
      yumvars['basearch'] = startupconf.basearch
      yumvars['arch'] = startupconf.arch
      yumvars['releasever'] = startupconf.releasever
-@@ -915,22 +1120,12 @@ def readMainConfig(startupconf):
+@@ -915,22 +1123,12 @@ def readMainConfig(startupconf):
          ir_path = varReplace(ir_path, yumvars)
          setattr(yumconf, option, ir_path)
      
@@ -197646,7 +197762,7 @@ index d09511f..8eab5bc 100644
  
      # These can use the above FS yumvars
      for option in ('cachedir', 'logfile', 'persistdir'):
-@@ -956,6 +1151,12 @@ def readMainConfig(startupconf):
+@@ -956,6 +1154,12 @@ def readMainConfig(startupconf):
      return yumconf
  
  def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
@@ -197659,7 +197775,7 @@ index d09511f..8eab5bc 100644
      parser = ConfigParser()
      confpp_obj = ConfigPreProcessor(configfile)
      try:
-@@ -970,17 +1171,16 @@ def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
+@@ -970,17 +1174,16 @@ def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
  
  
  def getOption(conf, section, name, option):
@@ -197687,7 +197803,7 @@ index d09511f..8eab5bc 100644
      try: 
          val = conf.get(section, name)
      except (NoSectionError, NoOptionError):
-@@ -1010,7 +1210,10 @@ def _getsysver(installroot, distroverpkg):
+@@ -1010,7 +1213,10 @@ def _getsysver(installroot, distroverpkg):
      ts = rpmUtils.transaction.initReadOnlyTransaction(root=installroot)
      ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
      try:
@@ -197699,7 +197815,7 @@ index d09511f..8eab5bc 100644
      except TypeError, e:
          # This is code for "cannot open rpmdb"
          # this is for pep 352 compliance on python 2.6 and above :(
-@@ -1028,25 +1231,44 @@ def _getsysver(installroot, distroverpkg):
+@@ -1028,25 +1234,44 @@ def _getsysver(installroot, distroverpkg):
      if idx.count() == 0:
          releasever = '$releasever'
      else:
@@ -197755,7 +197871,7 @@ index d09511f..8eab5bc 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 +1276,22 @@ def writeRawRepoFile(repo,only=None):
+@@ -1054,6 +1279,22 @@ def writeRawRepoFile(repo,only=None):
          for sect in ini._sections.keys():
              if varReplace(sect, repo.yumvar) == repo.id:
                  section_id = sect
@@ -197778,7 +197894,7 @@ index d09511f..8eab5bc 100644
      
      # Updated the ConfigParser with the changed values    
      cfgOptions = repo.cfg.options(repo.id)
-@@ -1069,7 +1307,7 @@ def writeRawRepoFile(repo,only=None):
+@@ -1069,7 +1310,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
@@ -197787,7 +197903,7 @@ index d09511f..8eab5bc 100644
              ovalue = ini[section_id][name]
  
          if name not in cfgOptions and option.default == value:
-@@ -1080,6 +1318,48 @@ def writeRawRepoFile(repo,only=None):
+@@ -1080,6 +1321,48 @@ def writeRawRepoFile(repo,only=None):
      fp.write(str(ini))
      fp.close()
  
@@ -198997,10 +199113,10 @@ index bca9651..00c17ad 100644
          else:
 diff --git a/yum/fssnapshots.py b/yum/fssnapshots.py
 new file mode 100755
-index 0000000..e912ea1
+index 0000000..9af252d
 --- /dev/null
 +++ b/yum/fssnapshots.py
-@@ -0,0 +1,347 @@
+@@ -0,0 +1,345 @@
 +
 +
 +import os
@@ -199058,9 +199174,6 @@ index 0000000..e912ea1
 +    names = lvm.listVgNames()
 +
 +    if not names: # Could be just broken...
-+        if not os.path.exists("/sbin/lvm"):
-+            return [] # Minimal install etc.
-+
 +        p = subprocess.Popen(["/sbin/lvm", "vgs", "-o", "vg_name"],
 +                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 +        err = p.wait()
@@ -199149,7 +199262,8 @@ index 0000000..e912ea1
 +            devices = []
 +
 +        self.version = _ver
-+        self.available = bool(lvm)
++        # Parts of the API seem to work even when lvm is not actually installed, hence the path test
++        self.available = bool(lvm and os.path.exists("/sbin/lvm"))
 +        self.postfix_static = "_yum_"
 +        self._postfix = None
 +        self._root = root
@@ -199349,7 +199463,7 @@ index 0000000..e912ea1
 +
 +        return ret
 diff --git a/yum/history.py b/yum/history.py
-index 5385bd1..fd80191 100644
+index 5385bd1..d08837c 100644
 --- a/yum/history.py
 +++ b/yum/history.py
 @@ -20,6 +20,7 @@
@@ -199544,7 +199658,18 @@ index 5385bd1..fd80191 100644
          
          # make an addon path for where we're going to stick 
          # random additional history info - probably from plugins and what-not
-@@ -638,13 +741,15 @@ class YumHistory:
+@@ -635,16 +738,26 @@ class YumHistory:
+             # it's deep yum stuff and there should only be one yum.
+             executeSQL(self._conn.cursor(), "PRAGMA locking_mode = EXCLUSIVE")
+ 
++            # See: http://sqlite.org/pragma.html#pragma_synchronous
++            #  It's far from the end of the world if the history DB dies, and
++            # NORMAL is very safe already. FULL means that verifyTransaction()
++            # does an fsync() for each package, which sucks.
++            executeSQL(self._conn.cursor(), "PRAGMA synchronous = NORMAL")
++            # Could/should do this when installroot'ing?
++            # executeSQL(self._conn.cursor(), "PRAGMA synchronous = OFF")
++
          return self._conn.cursor()
      def _commit(self):
          return self._conn.commit()
@@ -199561,7 +199686,7 @@ index 5385bd1..fd80191 100644
          cur = self._get_cursor()
          executeSQL(cur, """SELECT pkgtupid, checksum FROM pkgtups
                             WHERE name=? AND arch=? AND
-@@ -659,6 +764,9 @@ class YumHistory:
+@@ -659,6 +772,9 @@ class YumHistory:
              if checksum == sql_checksum:
                  return sql_pkgtupid
          
@@ -199571,7 +199696,7 @@ index 5385bd1..fd80191 100644
          (n,a,e,v,r) = pkgtup
          (n,a,e,v,r) = (to_unicode(n),to_unicode(a),
                         to_unicode(e),to_unicode(v),to_unicode(r))
-@@ -674,23 +782,28 @@ class YumHistory:
+@@ -674,23 +790,28 @@ class YumHistory:
                                  (name, arch, epoch, version, release)
                                  VALUES (?, ?, ?, ?, ?)""", (n,a,e,v,r))
          return cur.lastrowid
@@ -199608,7 +199733,7 @@ index 5385bd1..fd80191 100644
  
      @staticmethod
      def txmbr2state(txmbr):
-@@ -984,7 +1097,8 @@ class YumHistory:
+@@ -984,7 +1105,8 @@ class YumHistory:
                        ORDER BY name ASC, epoch ASC""", (tid,))
          ret = []
          for row in cur:
@@ -199618,7 +199743,7 @@ index 5385bd1..fd80191 100644
              ret.append(obj)
          return ret
      def _old_data_pkgs(self, tid):
-@@ -998,7 +1112,7 @@ class YumHistory:
+@@ -998,7 +1120,7 @@ class YumHistory:
          ret = []
          for row in cur:
              obj = YumHistoryPackageState(row[0],row[1],row[2],row[3],row[4],
@@ -199627,7 +199752,7 @@ index 5385bd1..fd80191 100644
              obj.done     = row[6] == 'TRUE'
              obj.state_installed = None
              if _sttxt2stcode[obj.state] in TS_INSTALL_STATES:
-@@ -1018,7 +1132,8 @@ class YumHistory:
+@@ -1018,7 +1140,8 @@ class YumHistory:
                        ORDER BY name ASC, epoch ASC""", (tid,))
          ret = []
          for row in cur:
@@ -199637,7 +199762,7 @@ index 5385bd1..fd80191 100644
              ret.append(obj)
          return ret
      def _old_prob_pkgs(self, rpid):
-@@ -1032,7 +1147,8 @@ class YumHistory:
+@@ -1032,7 +1155,8 @@ class YumHistory:
                        ORDER BY name ASC, epoch ASC""", (rpid,))
          ret = []
          for row in cur:
@@ -199647,7 +199772,7 @@ index 5385bd1..fd80191 100644
              obj.main = row[6] == 'TRUE'
              ret.append(obj)
          return ret
-@@ -1091,7 +1207,11 @@ class YumHistory:
+@@ -1091,7 +1215,11 @@ class YumHistory:
          if tids and len(tids) <= yum.constants.PATTERNS_INDEXED_MAX:
              params = tids = list(set(tids))
              sql += " WHERE tid IN (%s)" % ", ".join(['?'] * len(tids))
@@ -199660,7 +199785,7 @@ index 5385bd1..fd80191 100644
          if limit is not None:
              sql += " LIMIT " + str(limit)
          executeSQL(cur, sql, params)
-@@ -1151,6 +1271,127 @@ class YumHistory:
+@@ -1151,6 +1279,127 @@ class YumHistory:
          assert len(ret) == 1
          return ret[0]
  
@@ -199788,7 +199913,7 @@ index 5385bd1..fd80191 100644
      def _yieldSQLDataList(self, patterns, fields, ignore_case):
          """Yields all the package data for the given params. """
  
-@@ -1182,6 +1423,17 @@ class YumHistory:
+@@ -1182,6 +1431,17 @@ class YumHistory:
          if cur is None:
              return set()
  
@@ -199806,7 +199931,7 @@ index 5385bd1..fd80191 100644
          data = _setupHistorySearchSQL(patterns, ignore_case)
          (need_full, npatterns, fields, names) = data
  
-@@ -1220,6 +1472,48 @@ class YumHistory:
+@@ -1220,6 +1480,48 @@ class YumHistory:
              tids.add(row[0])
          return tids
  
@@ -199855,7 +199980,7 @@ index 5385bd1..fd80191 100644
      _update_ops_2 = ['''\
  \
   CREATE TABLE trans_skip_pkgs (
-@@ -1307,6 +1601,8 @@ class YumHistory:
+@@ -1307,6 +1609,8 @@ class YumHistory:
          self._cached_updated_2 = True
          return True
  
@@ -199864,7 +199989,7 @@ index 5385bd1..fd80191 100644
      def _create_db_file(self):
          """ Create a new history DB file, populating tables etc. """
  
-@@ -1321,8 +1617,10 @@ class YumHistory:
+@@ -1321,8 +1625,10 @@ class YumHistory:
              if os.path.exists(_db_file + '-journal'):
                  os.rename(_db_file  + '-journal', _db_file + '-journal.old')
          self._db_file = _db_file
@@ -199876,7 +200001,7 @@ index 5385bd1..fd80191 100644
              # make them default to 0600 - sysadmin can change it later
              # if they want
              fo = os.open(self._db_file, os.O_CREAT, 0600)
-@@ -1374,7 +1672,10 @@ class YumHistory:
+@@ -1374,7 +1680,10 @@ class YumHistory:
              cur.execute(op)
          for op in self._update_ops_2:
              cur.execute(op)
@@ -200801,7 +200926,7 @@ index 4af563a..a702ac1 100644
          self.obsoletes = {} #obs[obsoletename] = [pkg1, pkg2, pkg3] 
                   #the package lists are packages that obsolete the key name
 diff --git a/yum/packages.py b/yum/packages.py
-index 5ef9951..b219ada 100644
+index 5ef9951..8365f16 100644
 --- a/yum/packages.py
 +++ b/yum/packages.py
 @@ -38,6 +38,7 @@ import struct
@@ -201073,7 +201198,25 @@ index 5ef9951..b219ada 100644
          # Hacky way to get rid of version numbers...
          ix = val.find('> ')
          if ix != -1:
-@@ -859,7 +921,8 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -843,6 +905,17 @@ class YumAvailablePackage(PackageObject, RpmBase):
+         return self.checksums[0][1]
+     checksum = property(_checksum)
+ 
++
++    def _get_cashe(self):
++        if not hasattr(self, '_cashe_obj'):
++            if hasattr(self.repo, '_cashe') and self.repo._cashe is not None:
++                (csum_type, csum) = self.returnIdSum()
++                self._cashe_obj = self.repo._cashe.get(csum_type, csum)
++            else:
++                self._cashe_obj = None
++        return self._cashe_obj
++    _cashe = property(_get_cashe)
++
+     def getDiscNum(self):
+         if self.basepath is None:
+             return None
+@@ -859,7 +932,8 @@ class YumAvailablePackage(PackageObject, RpmBase):
          try:
              hdr = rpmUtils.miscutils.hdrFromPackage(ts, rpmfile)
          except rpmUtils.RpmUtilsError:
@@ -201083,7 +201226,7 @@ index 5ef9951..b219ada 100644
          return hdr
          
      def returnLocalHeader(self):
-@@ -871,9 +934,11 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -871,9 +945,11 @@ class YumAvailablePackage(PackageObject, RpmBase):
                  hlist = rpm.readHeaderListFromFile(self.localHdr())
                  hdr = hlist[0]
              except (rpm.error, IndexError):
@@ -201097,7 +201240,50 @@ index 5ef9951..b219ada 100644
  
          return hdr
  
-@@ -1063,10 +1128,10 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -896,7 +972,7 @@ class YumAvailablePackage(PackageObject, RpmBase):
+ 
+         return self.hdrpath
+     
+-    def verifyLocalPkg(self):
++    def verifyLocalPkg(self, from_cashe=False):
+         """check the package checksum vs the localPkg
+            return True if pkg is good, False if not"""
+ 
+@@ -905,7 +981,10 @@ class YumAvailablePackage(PackageObject, RpmBase):
+         try:
+             nst = os.stat(self.localPkg())
+         except OSError, e:
++            if self._cashe and self._cashe.load(self.localPkg()):
++                return self.verifyLocalPkg(from_cashe=True)
+             return False
++
+         if (hasattr(self, '_verify_local_pkg_cache') and
+             self._verify_local_pkg_cache):
+             ost = self._verify_local_pkg_cache
+@@ -921,12 +1000,22 @@ class YumAvailablePackage(PackageObject, RpmBase):
+             filesum = misc.checksum(csum_type, self.localPkg(),
+                                     datasize=self.packagesize)
+         except Errors.MiscError:
++            if from_cashe:
++                self._cashe.unlink()
++            elif nst.st_size >= self.packagesize:
++                return self.verifyLocalPkg() # Try: cashe
+             return False
+         
+         if filesum != csum:
++            if from_cashe:
++                self._cashe.unlink()
++            elif nst.st_size >= self.packagesize:
++                return self.verifyLocalPkg() # Try: cashe
+             return False
+         
+         self._verify_local_pkg_cache = nst
++        if not from_cashe and self._cashe and not self._cashe.exists:
++                self._cashe.save(self.localPkg())
+ 
+         return True
+ 
+@@ -1063,10 +1152,10 @@ class YumAvailablePackage(PackageObject, RpmBase):
          
          packager = url = ''
          if self.packager:
@@ -201110,7 +201296,7 @@ index 5ef9951..b219ada 100644
          (csum_type, csum, csumid) = self.checksums[0]
          msg = """
    <name>%s</name>
-@@ -1080,10 +1145,10 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -1080,10 +1169,10 @@ class YumAvailablePackage(PackageObject, RpmBase):
    <time file="%s" build="%s"/>
    <size package="%s" installed="%s" archive="%s"/>\n""" % (self.name, 
           self.arch, self.epoch, self.ver, self.rel, csum_type, csum, 
@@ -201124,7 +201310,7 @@ index 5ef9951..b219ada 100644
          
          msg += self._return_remote_location()
          return msg
-@@ -1121,6 +1186,10 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -1121,6 +1210,10 @@ class YumAvailablePackage(PackageObject, RpmBase):
          msg += self._dump_requires()
          msg += self._dump_pco('conflicts')         
          msg += self._dump_pco('obsoletes')         
@@ -201135,7 +201321,7 @@ index 5ef9951..b219ada 100644
          msg += self._dump_files(True)
          if msg[-1] != '\n':
              msg += """\n"""
-@@ -1131,9 +1200,9 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -1131,9 +1224,9 @@ class YumAvailablePackage(PackageObject, RpmBase):
      def _dump_pco(self, pcotype):
             
          msg = ""
@@ -201147,7 +201333,7 @@ index 5ef9951..b219ada 100644
              pcostring = '''      <rpm:entry name="%s"''' % misc.to_xml(name, attrib=True)
              if flags:
                  pcostring += ''' flags="%s"''' % misc.to_xml(flags, attrib=True)
-@@ -1151,25 +1220,14 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -1151,25 +1244,14 @@ class YumAvailablePackage(PackageObject, RpmBase):
          return msg
      
      def _dump_files(self, primary=False):
@@ -201181,7 +201367,7 @@ index 5ef9951..b219ada 100644
  
      def _requires_with_pre(self):
          raise NotImplementedError()
-@@ -1194,8 +1252,8 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -1194,8 +1276,8 @@ class YumAvailablePackage(PackageObject, RpmBase):
                          continue
                      newlist.append(i)
                  mylist = newlist
@@ -201192,7 +201378,7 @@ index 5ef9951..b219ada 100644
              if name.startswith('rpmlib('):
                  continue
              # this drops out requires that the pkg provides for itself.
-@@ -1217,19 +1275,22 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -1217,19 +1299,22 @@ class YumAvailablePackage(PackageObject, RpmBase):
                      prcostring += ''' ver="%s"''' % misc.to_xml(v, attrib=True)
                  if r:
                      prcostring += ''' rel="%s"''' % misc.to_xml(r, attrib=True)
@@ -201218,7 +201404,7 @@ index 5ef9951..b219ada 100644
          # We need to output them "backwards", so the oldest is first
          if not clog_limit:
              clogs = self.changelog
-@@ -1244,34 +1305,46 @@ class YumAvailablePackage(PackageObject, RpmBase):
+@@ -1244,34 +1329,46 @@ class YumAvailablePackage(PackageObject, RpmBase):
                  hack_ts += 1
              last_ts = ts
              ts += hack_ts
@@ -201283,7 +201469,7 @@ index 5ef9951..b219ada 100644
  
  #  This is a tweak on YumAvailablePackage() and is a base class for packages
  # which are actual rpms.
-@@ -1299,10 +1372,14 @@ class YumHeaderPackage(YumAvailablePackage):
+@@ -1299,10 +1396,14 @@ class YumHeaderPackage(YumAvailablePackage):
          self.pkgid = self.hdr[rpm.RPMTAG_SHA1HEADER]
          if not self.pkgid:
              self.pkgid = "%s.%s" %(self.hdr['name'], self.hdr['buildtime'])
@@ -201299,7 +201485,7 @@ index 5ef9951..b219ada 100644
      def _loadSummary(self):
          # Summaries "can be" empty, which rpm return [], see BZ 473239, *sigh*
          if self._loaded_summary is None:
-@@ -1338,6 +1415,20 @@ class YumHeaderPackage(YumAvailablePackage):
+@@ -1338,6 +1439,20 @@ class YumHeaderPackage(YumAvailablePackage):
      def _get_hdr(self):
          return self.hdr
  
@@ -201320,7 +201506,7 @@ index 5ef9951..b219ada 100644
      def _populatePrco(self):
          "Populate the package object with the needed PRCO interface."
  
-@@ -1345,6 +1436,17 @@ class YumHeaderPackage(YumAvailablePackage):
+@@ -1345,6 +1460,17 @@ class YumHeaderPackage(YumAvailablePackage):
                       "CONFLICT": misc.share_data("conflicts"),
                       "REQUIRE":  misc.share_data("requires"),
                       "PROVIDE":  misc.share_data("provides") }
@@ -201338,7 +201524,7 @@ index 5ef9951..b219ada 100644
          hdr = self._get_hdr()
          for tag in tag2prco:
              name = hdr[getattr(rpm, 'RPMTAG_%sNAME' % tag)]
-@@ -1353,16 +1455,48 @@ class YumHeaderPackage(YumAvailablePackage):
+@@ -1353,16 +1479,48 @@ class YumHeaderPackage(YumAvailablePackage):
                  continue
  
              lst = hdr[getattr(rpm, 'RPMTAG_%sFLAGS' % tag)]
@@ -201396,7 +201582,7 @@ index 5ef9951..b219ada 100644
      
      def tagByName(self, tag):
          warnings.warn("tagByName() will go away in a furture version of Yum.\n",
-@@ -1438,16 +1572,16 @@ class YumHeaderPackage(YumAvailablePackage):
+@@ -1438,16 +1596,16 @@ class YumHeaderPackage(YumAvailablePackage):
          # then create a _loadChangelog() method to put them into the 
          # self._changelog attr
          if len(self.hdr['changelogname']) > 0:
@@ -201417,7 +201603,7 @@ index 5ef9951..b219ada 100644
  
      def _is_pre_req(self, flag):
          """check the flags for a requirement, return 1 or 0 whether or not requires
-@@ -1708,6 +1842,7 @@ class YUMVerifyPackage:
+@@ -1708,6 +1866,7 @@ class YUMVerifyPackage:
          self._files = {}
  
  
@@ -201425,7 +201611,7 @@ index 5ef9951..b219ada 100644
  class _RPMVerifyPackage(YUMVerifyPackage):
      def __init__(self, po, fi, def_csum_type, patterns, all):
          YUMVerifyPackage.__init__(self, po)
-@@ -1720,18 +1855,30 @@ class _RPMVerifyPackage(YUMVerifyPackage):
+@@ -1720,18 +1879,30 @@ class _RPMVerifyPackage(YUMVerifyPackage):
          (fi, def_csum_type, patterns, all) = self._presetup
          del self._presetup
  
@@ -201457,7 +201643,7 @@ index 5ef9951..b219ada 100644
  
      def __contains__(self, *args, **kwargs):
          self._setup()
-@@ -1763,7 +1910,8 @@ class YumInstalledPackage(YumHeaderPackage):
+@@ -1763,7 +1934,8 @@ class YumInstalledPackage(YumHeaderPackage):
              self.yumdb_info = yumdb.get_package(self)
  
      def verify(self, patterns=[], deps=False, script=False,
@@ -201467,7 +201653,7 @@ index 5ef9951..b219ada 100644
          """verify that the installed files match the packaged checksum
             optionally verify they match only if they are in the 'pattern' list
             returns a tuple """
-@@ -1891,17 +2039,22 @@ class YumInstalledPackage(YumHeaderPackage):
+@@ -1891,17 +2063,22 @@ class YumInstalledPackage(YumHeaderPackage):
                      problems.append(prob)
  
                  my_mode = my_st.st_mode
@@ -201493,7 +201679,7 @@ index 5ef9951..b219ada 100644
                  if not pf.digest:
                      verify_digest = False
  
-@@ -1946,7 +2099,7 @@ class YumInstalledPackage(YumHeaderPackage):
+@@ -1946,7 +2123,7 @@ class YumInstalledPackage(YumHeaderPackage):
                              my_csum = digest_type + ':' + my_csum
                              my_st_size = fp.read_size
  
@@ -201502,7 +201688,7 @@ index 5ef9951..b219ada 100644
                          prob = _PkgVerifyProb('checksum',
                                                'checksum does not match', ftypes)
                          prob.database_value = csum
-@@ -2120,11 +2273,11 @@ class YumLocalPackage(YumHeaderPackage):
+@@ -2120,11 +2297,11 @@ class YumLocalPackage(YumHeaderPackage):
              relpath = self.localpath
  
          if self._baseurl:
@@ -202493,7 +202679,7 @@ index 3793bad..d5e50ac 100644
          pass
  
 diff --git a/yum/rpmsack.py b/yum/rpmsack.py
-index e289a7a..2d718c1 100644
+index e289a7a..229e1a1 100644
 --- a/yum/rpmsack.py
 +++ b/yum/rpmsack.py
 @@ -48,6 +48,17 @@ def _open_no_umask(*args):
@@ -202853,7 +203039,23 @@ index e289a7a..2d718c1 100644
                  if rreq[0].startswith('rpmlib'): continue
                  if rreq in providers:            continue
  
-@@ -1481,6 +1583,8 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -1474,6 +1576,15 @@ class RPMDBPackageSack(PackageSackBase):
+ 
+                 (req, flags, ver) = creq
+                 res = self.getProvides(req, flags, ver)
++
++                # Filter this pkg out, as self conflicts are allowed.
++                nres = {}
++                for conflicting_po in res:
++                    if conflicting_po.pkgtup[0] == pkg.pkgtup[0] and conflicting_po.pkgtup[2:] == pkg.pkgtup[2:]:
++                        continue
++                    nres[conflicting_po] = res[conflicting_po]
++                res = nres
++
+                 if not res:
+                     continue
+                 flags = yum.depsolve.flags.get(flags, flags)
+@@ -1481,6 +1592,8 @@ class RPMDBPackageSack(PackageSackBase):
                  prob = RPMDBProblemDependency(pkg, "conflicts", found=found,
                                                conflicts=res)
                  problems.append(prob)
@@ -202862,7 +203064,7 @@ index e289a7a..2d718c1 100644
          return problems
  
      def _iter_two_pkgs(self, ignore_provides):
-@@ -1529,14 +1633,31 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -1529,14 +1642,31 @@ class RPMDBPackageSack(PackageSackBase):
                  problems.append(RPMDBProblemObsoleted(pkg, obsoleter=obspo))
          return problems
  
@@ -202896,7 +203098,7 @@ index e289a7a..2d718c1 100644
                      problems.append(RPMDBProblemProvides(pkg, provide=provtup))
                      break
          return problems
-@@ -1562,11 +1683,11 @@ class RPMDBAdditionalData(object):
+@@ -1562,11 +1692,11 @@ class RPMDBAdditionalData(object):
          self._packages = {} # pkgid = dir
          if not os.path.exists(self.conf.db_path):
              try:
@@ -202911,7 +203113,7 @@ index e289a7a..2d718c1 100644
          else:
              if os.access(self.conf.db_path, os.W_OK):
                  self.conf.writable = True
-@@ -1622,6 +1743,7 @@ class RPMDBAdditionalDataPackage(object):
+@@ -1622,6 +1752,7 @@ class RPMDBAdditionalDataPackage(object):
                                  'installed_by', 'changed_by',
                                  'from_repo', 'from_repo_revision',
                                  'from_repo_timestamp', 'releasever',
@@ -202919,7 +203121,7 @@ index e289a7a..2d718c1 100644
                                  'command_line'])
  
      def __init__(self, conf, pkgdir, yumdb_cache=None):
-@@ -1706,9 +1828,11 @@ class RPMDBAdditionalDataPackage(object):
+@@ -1706,9 +1837,11 @@ class RPMDBAdditionalDataPackage(object):
          return os.path.normpath(self._mydir + '/' + attr)
  
      def _write(self, attr, value):
@@ -202932,7 +203134,7 @@ index e289a7a..2d718c1 100644
  
          attr = _sanitize(attr)
          if attr in self._read_cached_data:
-@@ -1753,7 +1877,7 @@ class RPMDBAdditionalDataPackage(object):
+@@ -1753,7 +1886,7 @@ class RPMDBAdditionalDataPackage(object):
          if attr.endswith('.tmp'):
              raise AttributeError, "%s has no attribute %s" % (self, attr)
  
@@ -204295,7 +204497,7 @@ index 0000000..8d91f88
 +    return txmbrs
 +
 diff --git a/yum/yumRepo.py b/yum/yumRepo.py
-index e5e9ece..b95b333 100644
+index e5e9ece..dc1d7db 100644
 --- a/yum/yumRepo.py
 +++ b/yum/yumRepo.py
 @@ -20,10 +20,12 @@ import time
@@ -205188,14 +205390,14 @@ index e5e9ece..b95b333 100644
 -        if len(downloading_with_size) == 1:
 -            downloading_no_size.extend(downloading_with_size)
 -            downloading_with_size = []
--
++    def _commonRetrieveDataMD_done(self, downloading):
++        """ Uncompress the downloaded metadata """
+ 
 -        remote_size = 0
 -        local_size  = 0
 -        for (ndata, nmdtype) in downloading_with_size: # Get total size...
 -            remote_size += int(ndata.size)
-+    def _commonRetrieveDataMD_done(self, downloading):
-+        """ Uncompress the downloaded metadata """
- 
+-
 -        for (ndata, nmdtype) in downloading_with_size:
 -            urlgrabber.progress.text_meter_total_size(remote_size, local_size)
 -            if not self._retrieveMD(nmdtype, retrieve_can_fail=True):
@@ -205295,7 +205497,7 @@ index e5e9ece..b95b333 100644
  
      def checkMD(self, fn, mdtype, openchecksum=False):
          """check the metadata type against its checksum"""
-@@ -1537,6 +1761,16 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1537,6 +1761,20 @@ class YumRepository(Repository, config.RepoConf):
          if size is not None:
              size = int(size)
  
@@ -205304,19 +205506,25 @@ index e5e9ece..b95b333 100644
 +            fsize = misc.stat_f(file)
 +            if fsize is not None: # We just got an xattr, so it should be there
 +                if size is None and l_csum == r_csum and fsize.st_size > 0:
++                    if not openchecksum:
++                        self._preload_to_cashe(r_ctype, r_csum, file)
 +                    return 1
 +                if size == fsize.st_size and l_csum == r_csum:
++                    if not openchecksum:
++                        self._preload_to_cashe(r_ctype, r_csum, file)
 +                    return 1
 +            # Anything goes wrong, run the checksums as normal...
 +
          try: # get the local checksum
              l_csum = self._checksum(r_ctype, file, datasize=size)
          except Errors.RepoError, e:
-@@ -1545,21 +1779,20 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1545,21 +1783,22 @@ class YumRepository(Repository, config.RepoConf):
              raise URLGrabError(-3, 'Error performing checksum')
  
          if l_csum == r_csum:
 +            _xattr_set_chksum(file, r_ctype, l_csum)
++            if not openchecksum:
++                self._preload_to_cashe(r_ctype, r_csum, file)
              return 1
          else:
              if check_can_fail:
@@ -205336,7 +205544,7 @@ index e5e9ece..b95b333 100644
          """ Internal function, use .retrieveMD() from outside yum. """
          #  Note that this can raise Errors.RepoMDError if mdtype doesn't exist
          # for this repo.
-@@ -1575,37 +1808,38 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1575,37 +1814,39 @@ class YumRepository(Repository, config.RepoConf):
              # got it, move along
              return local
  
@@ -205356,7 +205564,9 @@ index e5e9ece..b95b333 100644
 -                           self)
 -
          if (os.path.exists(local) or
-             self._preload_md_from_system_cache(os.path.basename(local))):
+-            self._preload_md_from_system_cache(os.path.basename(local))):
++            self._preload_md_from_system_cache(os.path.basename(local)) or 
++            self._preload_md_from_cashe(mdtype, local)):
              if self._checkMD(local, mdtype, check_can_fail=True):
                  self.retrieved[mdtype] = 1
                  return local # it's the same return the local one
@@ -205395,7 +205605,7 @@ index e5e9ece..b95b333 100644
              local = self._getFile(relative=remote,
                                    local=local, 
                                    copy_local=1,
-@@ -1613,18 +1847,18 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1613,18 +1854,18 @@ class YumRepository(Repository, config.RepoConf):
                                    checkfunc=checkfunc, 
                                    text=text,
                                    cache=self.http_caching == 'all',
@@ -205419,7 +205629,7 @@ index e5e9ece..b95b333 100644
              return local
  
  
-@@ -1646,13 +1880,21 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1646,13 +1887,21 @@ class YumRepository(Repository, config.RepoConf):
  
      def getGroups(self):
          """gets groups and returns group file path for the repository, if there
@@ -205444,7 +205654,7 @@ index e5e9ece..b95b333 100644
          self._callbacks_changed = True
  
      def setFailureObj(self, failure_obj):
-@@ -1681,7 +1923,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1681,7 +1930,7 @@ class YumRepository(Repository, config.RepoConf):
                  print "Could not read mirrorlist %s, error was \n%s" %(url, e)
                  content = []
              for line in content:
@@ -205453,7 +205663,7 @@ index e5e9ece..b95b333 100644
                      continue
                  mirror = line.rstrip() # no more trailing \n's
                  mirror = mirror.replace('$ARCH', '$BASEARCH')
-@@ -1701,7 +1943,8 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1701,7 +1950,8 @@ class YumRepository(Repository, config.RepoConf):
          fo = None
  
          cacheok = False
@@ -205463,7 +205673,7 @@ index e5e9ece..b95b333 100644
              cacheok = True
              fo = open(self.mirrorlist_file, 'r')
              url = 'file://' + self.mirrorlist_file # just to keep self._readMirrorList(fo,url) happy
-@@ -1713,7 +1956,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1713,7 +1963,7 @@ class YumRepository(Repository, config.RepoConf):
              ugopts = self._default_grabopts()
              try:
                  fo = urlgrabber.grabber.urlopen(url, **ugopts)
@@ -205472,7 +205682,7 @@ index e5e9ece..b95b333 100644
                  print "Could not retrieve mirrorlist %s error was\n%s: %s" % (url, e.args[0], misc.to_unicode(e.args[1]))
                  fo = None
  
-@@ -1740,7 +1983,11 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1740,7 +1990,11 @@ class YumRepository(Repository, config.RepoConf):
          if os.path.exists(destfn):
              if os.stat(fn)[stat.ST_CTIME] <= os.stat(destfn)[stat.ST_CTIME]:
                  return False
@@ -205485,7 +205695,35 @@ index e5e9ece..b95b333 100644
          return True
  
      def _preload_file_from_system_cache(self, filename, subdir='',
-@@ -1877,7 +2124,7 @@ def getMirrorList(mirrorlist, pdict = None):
+@@ -1769,6 +2023,27 @@ class YumRepository(Repository, config.RepoConf):
+            if possible"""
+         return self._preload_file_from_system_cache(filename)
+     
++    def _preload_to_cashe(self, checksum_type, checksum_data, filename):
++        if not hasattr(self, '_cashe') or self._cashe is None:
++            return False
++        obj = self._cashe.get(checksum_type, checksum_data)
++        if obj.exists:
++            return True
++        return obj.save(filename)
++
++    def _preload_from_cashe(self, checksum_type, checksum_data, filename):
++        if not hasattr(self, '_cashe') or self._cashe is None:
++            return False
++        obj = self._cashe.get(checksum_type, checksum_data)
++        return obj.load(filename)
++
++    def _preload_md_from_cashe(self, mdtype, filename):
++        """attempts to copy the metadata file from the system-wide cache,
++           if possible"""
++        thisdata = self.repoXML.getData(mdtype)
++        (checksum_type, checksum_data) = thisdata.checksum
++        return self._preload_from_cashe(checksum_type, checksum_data, filename)
++
+     def _preload_pkg_from_system_cache(self, pkg):
+         """attempts to copy the package from the system-wide cache,
+            if possible"""
+@@ -1877,7 +2152,7 @@ def getMirrorList(mirrorlist, pdict = None):
  
      try:
          fo = urlresolver.urlopen(url, proxies=pdict)
@@ -205495,7 +205733,7 @@ index e5e9ece..b95b333 100644
          fo = None
  
 diff --git a/yumcommands.py b/yumcommands.py
-index 4dcbea7..ac99150 100644
+index 4dcbea7..6fa11fa 100644
 --- a/yumcommands.py
 +++ b/yumcommands.py
 @@ -13,6 +13,7 @@
@@ -205506,7 +205744,7 @@ index 4dcbea7..ac99150 100644
  # Written by Seth Vidal
  
  """
-@@ -20,18 +21,26 @@ Classes for subcommands of the yum command line interface.
+@@ -20,18 +21,27 @@ Classes for subcommands of the yum command line interface.
  """
  
  import os
@@ -205532,10 +205770,11 @@ index 4dcbea7..ac99150 100644
  
  import yum.config
 +from yum import updateinfo
++from yum.packages import parsePackages
  
  def _err_mini_usage(base, basecmd):
      if basecmd not in base.yum_cli_commands:
-@@ -43,16 +52,24 @@ def _err_mini_usage(base, basecmd):
+@@ -43,16 +53,24 @@ def _err_mini_usage(base, basecmd):
      base.logger.critical(txt)
  
  def checkRootUID(base):
@@ -205563,7 +205802,7 @@ index 4dcbea7..ac99150 100644
      if not base.gpgKeyCheck():
          for repo in base.repos.listEnabled():
              if (repo.gpgcheck or repo.repo_gpgcheck) and not repo.gpgkey:
-@@ -75,31 +92,117 @@ For more information contact your distribution or package provider.
+@@ -75,31 +93,118 @@ For more information contact your distribution or package provider.
                  raise cli.CliError
  
  def checkPackageArg(base, basecmd, extcmds):
@@ -205609,6 +205848,10 @@ index 4dcbea7..ac99150 100644
 +    :raises: :class:`cli.CliError`
 +    """
 +    repos = base.repos.findRepos(extcmds[0], name_match=True, ignore_case=True)
++
++    if len(repos) > 1:
++        repos = [r for r in repos if r.isEnabled()]
++
 +    if not repos:
 +        base.logger.critical(
 +                _('Error: Need to pass a single valid repoid. to %s') % basecmd)
@@ -205616,9 +205859,6 @@ index 4dcbea7..ac99150 100644
 +        raise cli.CliError
 +
 +    if len(repos) > 1:
-+        repos = [r for r in repos if r.isEnabled()]
-+
-+    if len(repos) > 1:
 +        repos = ", ".join([r.ui_id for r in repos])
 +        base.logger.critical(
 +                _('Error: Need to pass only a single valid repoid. to %s, passed: %s') % (basecmd, repos))
@@ -205681,7 +205921,7 @@ index 4dcbea7..ac99150 100644
  
      for cmd in extcmds:
          if cmd not in VALID_ARGS:
-@@ -108,12 +211,14 @@ def checkCleanArg(base, basecmd, extcmds):
+@@ -108,12 +213,14 @@ def checkCleanArg(base, basecmd, extcmds):
              raise cli.CliError
  
  def checkShellArg(base, basecmd, extcmds):
@@ -205702,7 +205942,7 @@ index 4dcbea7..ac99150 100644
      """
      if len(extcmds) == 0:
          base.verbose_logger.debug(_("No argument to shell"))
-@@ -133,10 +238,12 @@ def checkShellArg(base, basecmd, extcmds):
+@@ -133,10 +240,12 @@ def checkShellArg(base, basecmd, extcmds):
          raise cli.CliError
  
  def checkEnabledRepo(base, possible_local_files=[]):
@@ -205718,7 +205958,7 @@ index 4dcbea7..ac99150 100644
      """
      if base.repos.listEnabled():
          return
-@@ -145,6 +252,11 @@ def checkEnabledRepo(base, possible_local_files=[]):
+@@ -145,6 +254,11 @@ def checkEnabledRepo(base, possible_local_files=[]):
          if lfile.endswith(".rpm") and os.path.exists(lfile):
              return
  
@@ -205730,7 +205970,7 @@ index 4dcbea7..ac99150 100644
      msg = _('There are no enabled repos.\n'
              ' Run "yum repolist all" to see the repos you have.\n'
              ' You can enable repos with yum-config-manager --enable <repo>')
-@@ -152,113 +264,296 @@ def checkEnabledRepo(base, possible_local_files=[]):
+@@ -152,113 +266,296 @@ def checkEnabledRepo(base, possible_local_files=[]):
      raise cli.CliError
  
  class YumCommand:
@@ -206053,9 +206293,18 @@ index 4dcbea7..ac99150 100644
  
  def _add_pkg_simple_list_lens(data, pkg, indent=''):
      """ Get the length of each pkg's column. Add that to data.
-@@ -289,22 +584,62 @@ def _list_cmd_calc_columns(base, ypl):
+@@ -288,23 +585,71 @@ def _list_cmd_calc_columns(base, ypl):
+     columns = base.calcColumns(data, remainder_column=1)
      return (-columns[0], -columns[1], -columns[2])
  
++def _cmdline_exclude(pkgs, cmdline_excludes):
++    """ Do an extra exclude for installed packages that match the cmd line. """
++    if not cmdline_excludes:
++        return pkgs
++    e,m,u = parsePackages(pkgs, cmdline_excludes)
++    excluded = set(e + m)
++    return [po for po in pkgs if po not in excluded]
++
  class InfoCommand(YumCommand):
 +    """A class containing methods needed by the cli to execute the
 +    info command.
@@ -206123,7 +206372,7 @@ index 4dcbea7..ac99150 100644
              update_pkgs = {}
              inst_pkgs   = {}
              local_pkgs  = {}
-@@ -341,6 +676,7 @@ class InfoCommand(YumCommand):
+@@ -341,14 +686,20 @@ class InfoCommand(YumCommand):
                          local_pkgs[(po.name, po.arch)] = po
  
              # Output the packages:
@@ -206131,7 +206380,10 @@ index 4dcbea7..ac99150 100644
              clio = base.conf.color_list_installed_older
              clin = base.conf.color_list_installed_newer
              clir = base.conf.color_list_installed_reinstall
-@@ -348,7 +684,9 @@ class InfoCommand(YumCommand):
+             clie = base.conf.color_list_installed_extra
++            if base.conf.query_install_excludes:
++                ypl.installed = _cmdline_exclude(ypl.installed,
++                                                 base.cmdline_excludes)
              rip = base.listPkgs(ypl.installed, _('Installed Packages'), basecmd,
                                  highlight_na=update_pkgs, columns=columns,
                                  highlight_modes={'>' : clio, '<' : clin,
@@ -206141,7 +206393,7 @@ index 4dcbea7..ac99150 100644
              clau = base.conf.color_list_available_upgrade
              clad = base.conf.color_list_available_downgrade
              clar = base.conf.color_list_available_reinstall
-@@ -356,6 +694,7 @@ class InfoCommand(YumCommand):
+@@ -356,6 +707,7 @@ class InfoCommand(YumCommand):
              rap = base.listPkgs(ypl.available, _('Available Packages'), basecmd,
                                  highlight_na=inst_pkgs, columns=columns,
                                  highlight_modes={'<' : clau, '>' : clad,
@@ -206149,7 +206401,7 @@ index 4dcbea7..ac99150 100644
                                                   '=' : clar, 'not in' : clai})
              rep = base.listPkgs(ypl.extras, _('Extra Packages'), basecmd,
                                  columns=columns)
-@@ -374,7 +713,7 @@ class InfoCommand(YumCommand):
+@@ -374,7 +726,7 @@ class InfoCommand(YumCommand):
                  for obtup in sorted(ypl.obsoletesTuples,
                                      key=operator.itemgetter(0)):
                      base.updatesObsoletesList(obtup, 'obsoletes',
@@ -206158,7 +206410,7 @@ index 4dcbea7..ac99150 100644
              else:
                  rop = base.listPkgs(ypl.obsoletes, _('Obsoleting Packages'),
                                      basecmd, columns=columns)
-@@ -389,65 +728,212 @@ class InfoCommand(YumCommand):
+@@ -389,65 +741,212 @@ class InfoCommand(YumCommand):
              return 0, []
  
      def needTs(self, base, basecmd, extcmds):
@@ -206377,7 +206629,7 @@ index 4dcbea7..ac99150 100644
          return _("Display, or use, the groups information")
      
      def _grp_setup_doCommand(self, base):
-@@ -459,7 +945,7 @@ class GroupsCommand(YumCommand):
+@@ -459,7 +958,7 @@ class GroupsCommand(YumCommand):
          except yum.Errors.GroupsError:
              return 1, [_('No Groups on which to run command')]
          except yum.Errors.YumBaseError, e:
@@ -206386,7 +206638,7 @@ index 4dcbea7..ac99150 100644
  
      def _grp_cmd(self, basecmd, extcmds):
          if basecmd in self.direct_commands:
-@@ -470,6 +956,10 @@ class GroupsCommand(YumCommand):
+@@ -470,6 +969,10 @@ class GroupsCommand(YumCommand):
          else:
              cmd = 'summary'
  
@@ -206397,7 +206649,7 @@ index 4dcbea7..ac99150 100644
          remap = {'update' : 'upgrade',
                   'erase' : 'remove',
                   'mark-erase' : 'mark-remove',
-@@ -479,32 +969,86 @@ class GroupsCommand(YumCommand):
+@@ -479,32 +982,86 @@ class GroupsCommand(YumCommand):
          return cmd, extcmds
  
      def doCheck(self, base, basecmd, extcmds):
@@ -206494,7 +206746,7 @@ index 4dcbea7..ac99150 100644
          cmd, extcmds = self._grp_cmd(basecmd, extcmds)
  
          self._grp_setup_doCommand(base)
-@@ -514,143 +1058,582 @@ class GroupsCommand(YumCommand):
+@@ -514,143 +1071,582 @@ class GroupsCommand(YumCommand):
          if cmd == 'list':
              return base.returnGroupLists(extcmds)
  
@@ -207103,7 +207355,7 @@ index 4dcbea7..ac99150 100644
              columns = _list_cmd_calc_columns(base, ypl)
              if len(ypl.updates) > 0:
                  local_pkgs = {}
-@@ -673,164 +1656,474 @@ class CheckUpdateCommand(YumCommand):
+@@ -673,164 +1669,474 @@ class CheckUpdateCommand(YumCommand):
                  for obtup in sorted(ypl.obsoletesTuples,
                                      key=operator.itemgetter(0)):
                      base.updatesObsoletesList(obtup, 'obsoletes',
@@ -207609,7 +207861,7 @@ index 4dcbea7..ac99150 100644
          def _repo_size(repo):
              ret = 0
              for pkg in repo.sack.returnPackages():
-@@ -838,12 +2131,9 @@ class RepoListCommand(YumCommand):
+@@ -838,12 +2144,9 @@ class RepoListCommand(YumCommand):
              return base.format_number(ret)
  
          def _repo_match(repo, patterns):
@@ -207624,7 +207876,7 @@ index 4dcbea7..ac99150 100644
                      return True
              return False
  
-@@ -857,7 +2147,10 @@ class RepoListCommand(YumCommand):
+@@ -857,7 +2160,10 @@ class RepoListCommand(YumCommand):
              arg = 'enabled'
          extcmds = map(lambda x: x.lower(), extcmds)
  
@@ -207636,7 +207888,7 @@ index 4dcbea7..ac99150 100644
          if arg != 'disabled' or extcmds:
              try:
                  # Setup so len(repo.sack) is correct
-@@ -866,6 +2159,13 @@ class RepoListCommand(YumCommand):
+@@ -866,6 +2172,13 @@ class RepoListCommand(YumCommand):
              except yum.Errors.RepoError:
                  if verbose:
                      raise
@@ -207650,7 +207902,7 @@ index 4dcbea7..ac99150 100644
  
          repos = base.repos.repos.values()
          repos.sort()
-@@ -924,111 +2224,113 @@ class RepoListCommand(YumCommand):
+@@ -924,111 +2237,113 @@ class RepoListCommand(YumCommand):
                  ui_enabled = dhibeg + _('disabled') + hiend
                  ui_endis_wid = utf8_width(_('disabled'))
  
@@ -207860,7 +208112,7 @@ index 4dcbea7..ac99150 100644
  
          if not verbose and cols:
              #  Work out the first (id) and last (enabled/disalbed/count),
-@@ -1088,21 +2390,64 @@ class RepoListCommand(YumCommand):
+@@ -1088,21 +2403,64 @@ class RepoListCommand(YumCommand):
          return 0, ['repolist: ' +to_unicode(locale.format("%d", tot_num, True))]
  
      def needTs(self, base, basecmd, extcmds):
@@ -207925,7 +208177,7 @@ index 4dcbea7..ac99150 100644
          if len(extcmds) == 0:
              base.usage()
              raise cli.CliError
-@@ -1147,82 +2492,230 @@ class HelpCommand(YumCommand):
+@@ -1147,82 +2505,230 @@ class HelpCommand(YumCommand):
          return help_output
  
      def doCommand(self, base, basecmd, extcmds):
@@ -208165,7 +208417,7 @@ index 4dcbea7..ac99150 100644
  
          def _append_repos(cols, repo_data):
              for repoid in sorted(repo_data):
-@@ -1264,7 +2757,7 @@ class VersionCommand(YumCommand):
+@@ -1264,7 +2770,7 @@ class VersionCommand(YumCommand):
  
          if vcmd == 'groupinfo':
              for group in groups:
@@ -208174,7 +208426,7 @@ index 4dcbea7..ac99150 100644
                      continue
                  print _(" Group   :"), group
                  print _(" Packages:")
-@@ -1284,11 +2777,35 @@ class VersionCommand(YumCommand):
+@@ -1284,11 +2790,35 @@ class VersionCommand(YumCommand):
  
              return 0, ['version groupinfo']
  
@@ -208211,7 +208463,7 @@ index 4dcbea7..ac99150 100644
                  data = base.rpmdb.simpleVersion(not verbose, groups=groups)
                  lastdbv = base.history.last()
                  if lastdbv is not None:
-@@ -1302,15 +2819,14 @@ class VersionCommand(YumCommand):
+@@ -1302,15 +2832,14 @@ class VersionCommand(YumCommand):
                  if groups:
                      for grp in sorted(data[2]):
                          if (vcmd.startswith("group-") and
@@ -208230,7 +208482,7 @@ index 4dcbea7..ac99150 100644
                  data = base.pkgSack.simpleVersion(not verbose, groups=groups)
                  if vcmd not in ('group-available', 'group-all'):
                      cols.append(("%s %s/%s" % (_("Available:"), rel, ba),
-@@ -1320,14 +2836,12 @@ class VersionCommand(YumCommand):
+@@ -1320,14 +2849,12 @@ class VersionCommand(YumCommand):
                  if groups:
                      for grp in sorted(data[2]):
                          if (vcmd.startswith("group-") and
@@ -208246,7 +208498,7 @@ index 4dcbea7..ac99150 100644
  
          data = {'rid' : {}, 'ver' : {}}
          for (rid, ver) in cols:
-@@ -1344,6 +2858,14 @@ class VersionCommand(YumCommand):
+@@ -1344,6 +2871,14 @@ class VersionCommand(YumCommand):
          return 0, ['version']
  
      def needTs(self, base, basecmd, extcmds):
@@ -208261,7 +208513,7 @@ index 4dcbea7..ac99150 100644
          vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1352,25 +2874,74 @@ class VersionCommand(YumCommand):
+@@ -1352,25 +2887,74 @@ class VersionCommand(YumCommand):
              return True
          return vcmd in ('available', 'all', 'group-available', 'group-all')
  
@@ -208337,7 +208589,7 @@ index 4dcbea7..ac99150 100644
              return 2, ["Repeating transaction %u" % (old.tid,)]
  
      def _hcmd_undo(self, base, extcmds):
-@@ -1426,12 +2997,60 @@ class HistoryCommand(YumCommand):
+@@ -1426,12 +3010,60 @@ class HistoryCommand(YumCommand):
      def _hcmd_new(self, base, extcmds):
          base.history._create_db_file()
  
@@ -208399,7 +208651,7 @@ index 4dcbea7..ac99150 100644
          if extcmds and extcmds[0] not in cmds:
              base.logger.critical(_('Invalid history sub-command, use: %s.'),
                                   ", ".join(cmds))
-@@ -1439,11 +3058,24 @@ class HistoryCommand(YumCommand):
+@@ -1439,11 +3071,24 @@ class HistoryCommand(YumCommand):
          if extcmds and extcmds[0] in ('repeat', 'redo', 'undo', 'rollback', 'new'):
              checkRootUID(base)
              checkGPGKey(base)
@@ -208425,7 +208677,7 @@ index 4dcbea7..ac99150 100644
          vcmd = 'list'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1468,29 +3100,88 @@ class HistoryCommand(YumCommand):
+@@ -1468,29 +3113,88 @@ class HistoryCommand(YumCommand):
              ret = self._hcmd_rollback(base, extcmds)
          elif vcmd == 'new':
              ret = self._hcmd_new(base, extcmds)
@@ -208514,7 +208766,7 @@ index 4dcbea7..ac99150 100644
          chkcmd = 'all'
          if extcmds:
              chkcmd = extcmds
-@@ -1505,33 +3196,1745 @@ class CheckRpmdbCommand(YumCommand):
+@@ -1505,33 +3209,1748 @@ class CheckRpmdbCommand(YumCommand):
          return rc, ['%s %s' % (basecmd, chkcmd)]
  
      def needTs(self, base, basecmd, extcmds):
@@ -208708,8 +208960,8 @@ index 4dcbea7..ac99150 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.
 +
@@ -209107,8 +209359,8 @@ index 4dcbea7..ac99150 100644
 +        if cmd in ('info', 'list'):
 +            return InfoCommand().needTs(base, cmd, extcmds[2:])
 +
-         return True
- 
++        return True
++
 +    def cacheRequirement(self, base, basecmd, extcmds):
 +        """Return the cache requirements for the remote repos.
 +
@@ -209592,11 +209844,13 @@ index 4dcbea7..ac99150 100644
 +            subcommand = 'summary'
 +
 +        if not base.fssnap.available:
-+            if not base.rpmdb.searchNames(['python-lvm']):
-+                print _("Snapshot support not available, no python-lvm package installed.")
-+            else:
-+                print _("Snapshot support not available, python-lvm is old/broken.")
-+            return 0, [basecmd + ' ' + subcommand + ' done']
++            msg = _("Snapshot support not available, please check your lvm installation.")
++            if not base.rpmdb.searchNames(['lvm2']):
++                msg += " " + _("No lvm2 package installed.")
++            if not base.rpmdb.searchNames(['lvm2-python-libs']):
++                msg += " " + _("No lvm2-python-libs package installed.")
++            print msg
++            return 1, [basecmd + ' ' + subcommand + ' done']
 +
 +        if subcommand == 'list':
 +            snaps = base.fssnap.old_snapshots()
@@ -209629,10 +209883,11 @@ index 4dcbea7..ac99150 100644
 +        if subcommand == 'create':
 +            tags = {'*': ['reason=manual']}
 +            pc = base.conf.fssnap_percentage
-+            for (odev, ndev) in base.fssnap.snapshot(pc, tags=tags):
-+                print _("Created snapshot from %s, results is: %s") %(odev,ndev)
-+            else:
++            snaps = base.fssnap.snapshot(pc, tags=tags)
++            if not snaps:
 +                print _("Failed to create snapshots")
++            for (odev, ndev) in snaps:
++                print _("Created snapshot from %s, results is: %s") %(odev,ndev)
 +
 +        if subcommand == 'summary':
 +            snaps = base.fssnap.old_snapshots()
diff --git a/yum.spec b/yum.spec
index 5b0c8a0..216c42b 100644
--- a/yum.spec
+++ b/yum.spec
@@ -64,7 +64,7 @@ BuildRequires: bash-completion
 Summary: RPM package installer/updater/manager
 Name: yum
 Version: 3.4.3
-Release: 155%{?dist}
+Release: 156%{?dist}
 License: GPLv2+
 Group: System Environment/Base
 Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz
@@ -510,6 +510,19 @@ exit 0
 %endif
 
 %changelog
+* Wed Mar  4 2015 James Antill <james at fedoraproject.org> - 3.4.3-156
+- update to latest HEAD
+- Have "yum check" ignore self conflicts.
+- Add simple testcase for installing older intermediate kernel. BZ 1063181.
+- Don't look for upgrades for install only packages. BZ 1063181.
+- check if repos list is empty after excluding disabled repos. BZ 1109473.
+- Allow caching local repos. BZ 1125387.
+- Expect KB as well as MB in disk requirements message from rpm. BZ 1051931.
+- Multiple lvm fixes. BZ 1047793, BZ 1145485.
+- Change the sqlite synchronous mode for the history file, to NORMAL.
+- Add CAShe config. and objects, use it for MD and packages.
+- Add query_install_excludes conf./docs and use it for list/info/search/prov
+
 * Tue Sep 16 2014 James Antill <james at fedoraproject.org> - 3.4.3-155
 - update to latest HEAD
 - Workaround history searching for [abc] character lists failures. BZ 1096147.


More information about the scm-commits mailing list