[yum] yum-cron: EmailEmitter failure should not be fatal. BZ 1055042

Valentina Mukhamedzhanova vmukhame at fedoraproject.org
Wed Jan 22 10:17:18 UTC 2014


commit 53d526d47a8872c07e0e101b4cfac60a00ffa7fe
Author: Valentina Mukhamedzhanova <vmukhame at redhat.com>
Date:   Wed Jan 22 11:17:34 2014 +0100

    yum-cron: EmailEmitter failure should not be fatal. BZ 1055042
    
    - yum-cron: Add a retry loop around doLock().
    - _set_repos_cache_req(): Handle missing cachedir. BZ 1044080
    - repo-pkgs: Fix repoid parsing. BZ 1055132.
    - Fix bash completion for 'autoremove'
    - downloadonly: unlink .tmp files on ctrl-c. BZ 1045806
    - repo-pkgs <repoid> info|list shouldn't require root UID.
    - doPackageLists(repoid=<repoid>): filter 2nd ipkg lookup. BZ 1056489

 yum-HEAD.patch |  533 +++++++++++++++++++++++++++++++++-----------------------
 yum.spec       |   12 ++-
 2 files changed, 324 insertions(+), 221 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index 9c17f00..0cbbe39 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..5b44b2c
+index 6056d38..c8884ae
 --- a/cli.py
 +++ b/cli.py
 @@ -25,7 +25,7 @@ import sys
@@ -350,11 +350,11 @@ index 6056d38..5b44b2c
 +        ts_min = None
 +        ts_max = None
 +        for repo in self.repos.listEnabled():
-+            if not os.path.exists(repo.metadata_cookie):
++            try: rts = os.stat(repo.metadata_cookie).st_mtime
++            except (yum.Errors.RepoError, OSError):
 +                ts_min = None
 +                break
 +
-+            rts = os.stat(repo.metadata_cookie).st_mtime
 +            if not ts_min:
 +                ts_min = rts
 +                ts_max = rts
@@ -2743,14 +2743,14 @@ index 0000000..ad24788
 +    generateAll(os.getcwd(), os.getcwd())
 diff --git a/docs/yum-cron.8 b/docs/yum-cron.8
 new file mode 100644
-index 0000000..2af059d
+index 0000000..db50fc2
 --- /dev/null
 +++ b/docs/yum-cron.8
 @@ -0,0 +1,50 @@
 +.\" yum-cron - cron interface for yum
 +.TH "yum-cron" "8" ""  "Nick Jacek" ""
 +.SH "NAME"
-+yum-cron \- an interface to convieniently call yum from cron
++yum-cron \- an interface to conveniently call yum from cron
 +
 +.SH "SYNOPSIS"
 +\fByum-cron\fP [config-file]
@@ -4693,7 +4693,7 @@ index c60fa08..0000000
 -ts run
 -exit
 diff --git a/etc/yum.bash b/etc/yum.bash
-index f1e06e8..9dce01f 100644
+index f1e06e8..d0a8a0f 100644
 --- a/etc/yum.bash
 +++ b/etc/yum.bash
 @@ -1,53 +1,27 @@
@@ -4852,13 +4852,15 @@ index f1e06e8..9dce01f 100644
              return 0
              ;;
  
-@@ -183,16 +173,16 @@ _yum()
+@@ -182,101 +172,125 @@ _yum()
+         _get_comp_words_by_ref -n = cur prev words
  
      # Commands offered as completions
-     local cmds=( check check-update clean deplist distro-sync downgrade
+-    local cmds=( check check-update clean deplist distro-sync downgrade
 -        groupinfo groupinstall grouplist groupremove help history info install
 -        list makecache provides reinstall remove repolist resolvedep search
 -        shell update upgrade version )
++    local cmds=( autoremove check check-update clean deplist distro-sync downgrade
 +        groups help history info install list load-transaction makecache provides
 +        reinstall remove repolist search shell update upgrade version )
  
@@ -4873,7 +4875,17 @@ index f1e06e8..9dce01f 100644
              [[ ${words[i]} == $c ]] && cmd=$c && break
          done
      done
-@@ -205,78 +195,102 @@ _yum()
+ 
+     case $cmd in
+ 
++        autoremove|erase|remove)
++            _yum_atgroups "$cur" || _yum_list installed "$cur"
++            return 0
++            ;;
++
+         check|check-rpmdb)
+             COMPREPLY=( $( compgen -W 'dependencies duplicates all' \
+                 -- "$cur" ) )
              return 0
              ;;
  
@@ -4909,6 +4921,11 @@ index f1e06e8..9dce01f 100644
          downgrade|reinstall)
 -            _yum_binrpmfiles "$cur"
 -            _yum_list installed "$cur"
+-            return 0
+-            ;;
+-
+-        erase|remove)
+-            _yum_list installed "$cur"
 +            if ! _yum_atgroups "$cur" ; then
 +                _yum_binrpmfiles "$cur"
 +                _yum_list installed "$cur"
@@ -4916,12 +4933,6 @@ index f1e06e8..9dce01f 100644
              return 0
              ;;
  
-         erase|remove)
--            _yum_list installed "$cur"
-+            _yum_atgroups "$cur" || _yum_list installed "$cur"
-             return 0
-             ;;
- 
          group*)
 -            _yum_grouplist "" "$cur"
 +            if [[ ($cmd == groups || $cmd == group) && $prev == $cmd ]] ; then
@@ -183780,9 +183791,36 @@ index 6177fb1..ba65e55 100644
 +        self.assert_(self._pkg2txmbr(foo11).reason == 'user')
 +        self.assert_(self._pkg2txmbr(bar11).reason == 'blahg')
 diff --git a/test/skipbroken-tests.py b/test/skipbroken-tests.py
-index 812785a..68f5ef9 100644
+index 812785a..e2abc4c 100644
 --- a/test/skipbroken-tests.py
 +++ b/test/skipbroken-tests.py
+@@ -26,7 +26,7 @@ class SkipBrokenTests(DepsolveTests):
+ 
+     def _pkgstr_to_nevra(self, pkg_str):
+         '''
+-        Get a nevra from from a epoch:name-version-release.arch string
++        Get a nevra from from an epoch:name-version-release.arch string
+         @param pkg_str: package string
+         '''
+         res = REGEX_PKG.search(pkg_str)
+@@ -40,7 +40,7 @@ class SkipBrokenTests(DepsolveTests):
+ 
+     def repoString(self, pkg_str):
+         ''' 
+-        Add an available package from a epoch:name-version-release.arch string
++        Add an available package from an epoch:name-version-release.arch string
+         '''
+         (n,e,v,r,a) = self._pkgstr_to_nevra(pkg_str)
+         return self.repoPackage(n,v,r,e,a)   
+@@ -48,7 +48,7 @@ class SkipBrokenTests(DepsolveTests):
+             
+     def instString(self, pkg_str):
+         ''' 
+-        Add an installed package from a epoch:name-version-release.arch string
++        Add an installed package from an epoch:name-version-release.arch string
+         '''
+         (n,e,v,r,a) = self._pkgstr_to_nevra(pkg_str)
+         return self.instPackage(n,v,r,e,a)   
 @@ -81,7 +81,7 @@ class SkipBrokenTests(DepsolveTests):
          self.assertResult([])
  
@@ -183792,6 +183830,15 @@ index 812785a..68f5ef9 100644
          foo + foobar is skipped because barfoo is not provided
          bar stays in the transaction
          '''
+@@ -119,7 +119,7 @@ class SkipBrokenTests(DepsolveTests):
+     def testUpdateRequireOld(self):
+         '''update with missing req. is skipped
+         The foo-1.0 -> foo-2.0 update fails, because foo-tools-2.0 need by foo-2.0
+-        is not provided, the update should be skipped and result in a empty transaction
++        is not provided, the update should be skipped and result in an empty transaction
+         '''
+         po1 = self.instPackage('foo', '1')
+         po1.addRequires('foo-tools', 'EQ', ('0', '1', '0'))
 @@ -219,7 +219,7 @@ class SkipBrokenTests(DepsolveTests):
          self.assertResult([ipo, po1])
  
@@ -183867,7 +183914,7 @@ index 812785a..68f5ef9 100644
      def resolveCode(self,skip = False):
          solver = YumBase()
 diff --git a/test/testbase.py b/test/testbase.py
-index d0f22be..a31f7a6 100644
+index d0f22be..9d331c6 100644
 --- a/test/testbase.py
 +++ b/test/testbase.py
 @@ -55,6 +55,17 @@ class FakeConf(object):
@@ -183926,6 +183973,15 @@ index d0f22be..a31f7a6 100644
      def transactionResultVersion(self, rpmdbv):
          return
      def transactionReset(self):
+@@ -381,7 +402,7 @@ class FakeRpmDb(packageSack.PackageSack):
+ #######################################################################
+ 
+ class DepsolveTests(_DepsolveTestsBase):
+-    """Run depsolver on an manually  set up transaction.
++    """Run depsolver on a manually set up transaction.
+     You can add pkgs to self.rpmdb or self.tsInfo. See
+     yum/transactioninfo.py for details.
+     A typical test case looks like:
 diff --git a/test/yum-leak-test.py b/test/yum-leak-test.py
 index 760b770..dd64483 100755
 --- a/test/yum-leak-test.py
@@ -184359,7 +184415,7 @@ index fba02c5..a9270e2 100755
 diff --git a/utils.py b/utils.py
 old mode 100644
 new mode 100755
-index ced6ba0..28fdd70
+index ced6ba0..0b7191c
 --- a/utils.py
 +++ b/utils.py
 @@ -13,6 +13,9 @@
@@ -184621,7 +184677,7 @@ index ced6ba0..28fdd70
 -        """do a default setup for all the normal/necessary yum components,
 -           really just a shorthand for testing"""
 +        """Do a default setup for all the normal or necessary yum components;
-+           this method is mostly just a used for testing.
++           this method is mostly just used for testing.
 +        """
          # FIXME - we need another way to do this, I think.
          try:
@@ -184703,10 +184759,10 @@ index 0000000..28e1964
 +- Check if we're running as root; exit nicely.
 diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
 new file mode 100755
-index 0000000..6cbed94
+index 0000000..e1028be
 --- /dev/null
 +++ b/yum-cron/yum-cron.py
-@@ -0,0 +1,700 @@
+@@ -0,0 +1,711 @@
 +#!/usr/bin/python -tt
 +import os
 +import sys
@@ -184855,8 +184911,9 @@ index 0000000..6cbed94
 +class EmailEmitter(UpdateEmitter):
 +    """Emitter class to send messages via email."""
 +
-+    def __init__(self, opts):
++    def __init__(self, opts, logger):
 +        super(EmailEmitter, self).__init__(opts)        
++        self.logger = logger
 +        self.subject = ""
 +
 +    def updatesAvailable(self, summary):
@@ -184938,10 +184995,13 @@ index 0000000..6cbed94
 +        msg['To'] = ",".join(self.opts.email_to)
 +
 +        # Send the email
-+        s = smtplib.SMTP()
-+        s.connect(self.opts.email_host)
-+        s.sendmail(self.opts.email_from, self.opts.email_to, msg.as_string())
-+        s.close()
++        try:
++            s = smtplib.SMTP()
++            s.connect(self.opts.email_host)
++            s.sendmail(self.opts.email_from, self.opts.email_to, msg.as_string())
++            s.close()
++        except Exception, e:
++            self.logger.error("Failed to send an email to %s: %s" % (self.opts.email_host, e))
 +
 +
 +class StdIOEmitter(UpdateEmitter):
@@ -184967,6 +185027,8 @@ index 0000000..6cbed94
 +    system_name = Option(gethostname())
 +    output_width = IntOption(80)
 +    random_sleep = IntOption(0)
++    lock_retries = IntOption(5)
++    lock_sleep = IntOption(60)
 +    emit_via = ListOption(['email','stdio'])
 +    email_to = ListOption(["root"])
 +    email_from = Option("root")
@@ -185002,7 +185064,7 @@ index 0000000..6cbed94
 +        # Create the emitters, and add them to the list
 +        self.emitters = []
 +        if 'email' in self.opts.emit_via:
-+            self.emitters.append(EmailEmitter(self.opts))
++            self.emitters.append(EmailEmitter(self.opts, self.logger))
 +        if 'stdio' in self.opts.emit_via:
 +            self.emitters.append(StdIOEmitter(self.opts))
 +
@@ -185091,9 +185153,14 @@ index 0000000..6cbed94
 +    def acquireLock(self):
 +        """ Wrapper method around doLock to emit errors correctly."""
 +
-+        try:
-+            self.doLock()
-+        except yum.Errors.LockError, e:
++        i = 0
++        while True:
++            try: self.doLock(); break
++            except yum.Errors.LockError, e:
++                i += 1
++                if i < self.opts.lock_retries:
++                    sleep(self.opts.lock_sleep)
++                    continue
 +            self.logger.warn("Failed to acquire the yum lock: %s", e)
 +            sys.exit(1)
 +
@@ -186619,7 +186686,7 @@ index c1af4ad..70de539 100644
      pass
      
 diff --git a/yum/__init__.py b/yum/__init__.py
-index 99039e0..9fb88d4 100644
+index 99039e0..bbd20f3 100644
 --- a/yum/__init__.py
 +++ b/yum/__init__.py
 @@ -21,6 +21,7 @@ The Yum RPM software updater.
@@ -187451,7 +187518,15 @@ index 99039e0..9fb88d4 100644
                  if not self.tsInfo.exists(pkg.pkgtup):
                      self.verbose_logger.debug('SKIPBROKEN: Remove extra obsoleted %s (%s)' % (txmbr.po,pkg) )
                      self.tsInfo.remove(txmbr.po.pkgtup)
-@@ -1282,7 +1528,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1275,14 +1521,14 @@ class YumBase(depsolve.Depsolve):
+     def _checkUpdatedLeftovers(self):
+         """ 
+         If multiple packages is updated the same package
+-        and this package get removed because of an dep issue
++        and this package get removed because of a dep issue
+         then make sure that all the TS_UPDATED get removed.
+         """
+         for txmbr in self.tsInfo.getMembersWithState(None, [TS_UPDATED]):
              for pkg in txmbr.updated_by:
                  # check if the updating txmbr is in the transaction
                  # else remove the updated txmbr
@@ -187948,7 +188023,7 @@ index 99039e0..9fb88d4 100644
              if a is None:
                  return -1
              if b is None:
-@@ -1925,9 +2339,6 @@ class YumBase(depsolve.Depsolve):
+@@ -1925,12 +2339,11 @@ class YumBase(depsolve.Depsolve):
                  return 1
              return 0
          
@@ -187958,7 +188033,12 @@ index 99039e0..9fb88d4 100644
          errors = {}
          def adderror(po, msg):
              errors.setdefault(po, []).append(msg)
-@@ -1943,116 +2354,200 @@ class YumBase(depsolve.Depsolve):
++            if po.localpath.endswith('.tmp'):
++                misc.unlink_f(po.localpath) # won't resume this..
+ 
+         #  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 +2356,196 @@ class YumBase(depsolve.Depsolve):
          self.history.close()
  
          self.plugins.run('predownload', pkglist=pkglist)
@@ -188079,6 +188159,10 @@ index 99039e0..9fb88d4 100644
 +
 +                def checkfunc(obj, po=po):
 +                    self.verifyPkg(obj, po, 1)
++                    if po.localpath.endswith('.tmp'):
++                        rpmfile = po.localpath.rsplit('.', 2)[0]
++                        os.rename(po.localpath, rpmfile)
++                        po.localpath = rpmfile
 +                    local_size[0] += po.size
                      if hasattr(urlgrabber.progress, 'text_meter_total_size'):
                          urlgrabber.progress.text_meter_total_size(remote_size,
@@ -188167,29 +188251,21 @@ index 99039e0..9fb88d4 100644
 +                except Errors.RepoError, e:
 +                    adderror(po, exception2msg(e))
 +            if async:
-+                urlgrabber.grabber.parallel_wait()
++                try:
++                    urlgrabber.grabber.parallel_wait()
++                except KeyboardInterrupt:
++                    for po in remote_pkgs:
++                        if po.localpath.endswith('.tmp'):
++                            misc.unlink_f(po.localpath)
++                        elif isinstance(po, DeltaPackage) and po.rpm.localpath.endswith('.tmp'):
++                            misc.unlink_f(po.rpm.localpath)
++                    raise
 +            presto.dequeue_all()
 +            presto.wait()
 +
 +            if hasattr(urlgrabber.progress, 'text_meter_total_size'):
 +                urlgrabber.progress.text_meter_total_size(0)
 +
-+            if downloadonly:
-+                for po in remote_pkgs:
-+                    if not po.localpath.endswith('.tmp'):
-+                        # file:// repos don't "download"
-+                        continue
-+                    if po in errors:
-+                        # we may throw away partial file here- but we don't lock,
-+                        # so can't rename tempfile to rpmfile safely
-+                        misc.unlink_f(po.localpath)
-+                    else:
-+                        # verifyPkg() didn't complain, so (potentially)
-+                        # overwriting another copy should not be a problem
-+                        rpmfile = po.localpath.rsplit('.', 2)[0]
-+                        os.rename(po.localpath, rpmfile)
-+                        po.localpath = rpmfile
-+                    
 +            fatal = False
 +            for po in errors:
 +                if not isinstance(po, DeltaPackage):
@@ -188248,7 +188324,7 @@ index 99039e0..9fb88d4 100644
          if type(fo) is types.InstanceType:
              fo = fo.filename
              
-@@ -2076,9 +2571,12 @@ class YumBase(depsolve.Depsolve):
+@@ -2076,9 +2569,12 @@ class YumBase(depsolve.Depsolve):
          return 1
          
      def downloadHeader(self, po):
@@ -188263,7 +188339,7 @@ index 99039e0..9fb88d4 100644
          if hasattr(po, 'pkgtype') and po.pkgtype == 'local':
              return
                  
-@@ -2122,15 +2620,17 @@ class YumBase(depsolve.Depsolve):
+@@ -2122,15 +2618,17 @@ class YumBase(depsolve.Depsolve):
              return
  
      def sigCheckPkg(self, po):
@@ -188289,7 +188365,7 @@ index 99039e0..9fb88d4 100644
          if self._override_sigchecks:
              check = False
              hasgpgkey = 0
-@@ -2181,6 +2681,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2181,6 +2679,9 @@ class YumBase(depsolve.Depsolve):
          return result, msg
  
      def cleanUsedHeadersPackages(self):
@@ -188299,7 +188375,7 @@ index 99039e0..9fb88d4 100644
          filelist = []
          for txmbr in self.tsInfo:
              if txmbr.po.state not in TS_INSTALL_STATES:
-@@ -2189,6 +2692,8 @@ class YumBase(depsolve.Depsolve):
+@@ -2189,6 +2690,8 @@ class YumBase(depsolve.Depsolve):
                  continue
              if txmbr.po.repoid not in self.repos.repos:
                  continue
@@ -188308,7 +188384,7 @@ index 99039e0..9fb88d4 100644
              
              # make sure it's not a local file
              repo = self.repos.repos[txmbr.po.repoid]
-@@ -2218,27 +2723,42 @@ class YumBase(depsolve.Depsolve):
+@@ -2218,27 +2721,42 @@ class YumBase(depsolve.Depsolve):
                      _('%s removed'), fn)
          
      def cleanHeaders(self):
@@ -188353,7 +188429,7 @@ index 99039e0..9fb88d4 100644
          cachedir = self.conf.persistdir + "/rpmdb-indexes/"
          if not os.path.exists(cachedir):
              filelist = []
-@@ -2271,9 +2791,31 @@ class YumBase(depsolve.Depsolve):
+@@ -2271,9 +2789,31 @@ class YumBase(depsolve.Depsolve):
          return 0, [msg]
  
      def doPackageLists(self, pkgnarrow='all', patterns=None, showdups=None,
@@ -188388,7 +188464,7 @@ index 99039e0..9fb88d4 100644
          if showdups is None:
              showdups = self.conf.showdupesfromrepos
          ygh = misc.GenericHolder(iter=pkgnarrow)
-@@ -2295,6 +2837,8 @@ class YumBase(depsolve.Depsolve):
+@@ -2295,6 +2835,8 @@ class YumBase(depsolve.Depsolve):
              ndinst = {} # Newest versions by name.arch
              for po in self.rpmdb.returnPackages(patterns=patterns,
                                                  ignore_case=ic):
@@ -188397,7 +188473,7 @@ index 99039e0..9fb88d4 100644
                  dinst[po.pkgtup] = po
                  if showdups:
                      continue
-@@ -2304,8 +2848,13 @@ class YumBase(depsolve.Depsolve):
+@@ -2304,8 +2846,13 @@ class YumBase(depsolve.Depsolve):
              installed = dinst.values()
                          
              if showdups:
@@ -188412,7 +188488,7 @@ index 99039e0..9fb88d4 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2323,16 +2872,30 @@ class YumBase(depsolve.Depsolve):
+@@ -2323,16 +2870,31 @@ class YumBase(depsolve.Depsolve):
                      key = (pkg.name, pkg.arch)
                      if pkg.pkgtup in dinst:
                          reinstall_available.append(pkg)
@@ -188428,6 +188504,7 @@ index 99039e0..9fb88d4 100644
 +                        # is much slower than calling searchNevra(). *Sigh*
 +                        ipkgs = self.rpmdb.searchNevra(pkg.name,
 +                                                       arch=pkg.arch)
++                        ipkgs = misc.filter_pkgs_repoid(ipkgs, repoid)
 +                        if ipkgs:
 +                            ndinst[key] = sorted(ipkgs)[-1]
 +
@@ -188446,7 +188523,7 @@ index 99039e0..9fb88d4 100644
                  if len(matches) > 1:
                      updates.append(matches[0])
                      self.verbose_logger.log(logginglevels.DEBUG_1,
-@@ -2352,13 +2915,19 @@ class YumBase(depsolve.Depsolve):
+@@ -2352,13 +2914,19 @@ class YumBase(depsolve.Depsolve):
          elif pkgnarrow == 'installed':
              installed = self.rpmdb.returnPackages(patterns=patterns,
                                                    ignore_case=ic)
@@ -188467,7 +188544,7 @@ index 99039e0..9fb88d4 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2392,9 +2961,21 @@ class YumBase(depsolve.Depsolve):
+@@ -2392,9 +2960,21 @@ class YumBase(depsolve.Depsolve):
              avail = set(avail)
              for po in self.rpmdb.returnPackages(patterns=patterns,
                                                  ignore_case=ic):
@@ -188489,7 +188566,7 @@ index 99039e0..9fb88d4 100644
          # obsoleting packages (and what they obsolete)
          elif pkgnarrow == 'obsoletes':
              self.conf.obsoletes = 1
-@@ -2402,6 +2983,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2402,6 +2982,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)
@@ -188497,7 +188574,7 @@ index 99039e0..9fb88d4 100644
                  instpo = self.getInstalledPackageObject(instTup)
                  for po in pkgs:
                      obsoletes.append(po)
-@@ -2433,7 +3015,12 @@ class YumBase(depsolve.Depsolve):
+@@ -2433,7 +3014,12 @@ class YumBase(depsolve.Depsolve):
              recentlimit = now-(self.conf.recent*86400)
              if showdups:
                  avail = self.pkgSack.returnPackages(patterns=patterns,
@@ -188511,7 +188588,7 @@ index 99039e0..9fb88d4 100644
              else:
                  try:
                      avail = self.pkgSack.returnNewestByNameArch(patterns=patterns,
-@@ -2461,14 +3048,13 @@ class YumBase(depsolve.Depsolve):
+@@ -2461,14 +3047,13 @@ class YumBase(depsolve.Depsolve):
  
          
      def findDeps(self, pkgs):
@@ -188531,7 +188608,7 @@ index 99039e0..9fb88d4 100644
          results = {}
  
          for pkg in pkgs:
-@@ -2495,10 +3081,22 @@ class YumBase(depsolve.Depsolve):
+@@ -2495,10 +3080,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):
@@ -188558,7 +188635,7 @@ index 99039e0..9fb88d4 100644
          sql_fields = []
          for f in fields:
              sql_fields.append(RPM_TO_SQLITE.get(f, f))
-@@ -2614,7 +3212,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2614,7 +3211,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.
@@ -188567,7 +188644,7 @@ index 99039e0..9fb88d4 100644
          # either, so it's pretty thankless. HTH. HAND.
          # By default just sort using package sorting
          sort_func = operator.itemgetter(0)
-@@ -2661,6 +3259,14 @@ class YumBase(depsolve.Depsolve):
+@@ -2661,6 +3258,14 @@ class YumBase(depsolve.Depsolve):
                      yield (po, vs)
  
      def searchPackageTags(self, criteria):
@@ -188582,7 +188659,7 @@ index 99039e0..9fb88d4 100644
          results = {} # name = [(criteria, taglist)]
          for c in criteria:
              c = c.lower()
-@@ -2677,11 +3283,16 @@ class YumBase(depsolve.Depsolve):
+@@ -2677,11 +3282,16 @@ class YumBase(depsolve.Depsolve):
          return results
          
      def searchPackages(self, fields, criteria, callback=None):
@@ -188604,7 +188681,7 @@ index 99039e0..9fb88d4 100644
          warnings.warn(_('searchPackages() will go away in a future version of Yum.\
                        Use searchGenerator() instead. \n'),
                  Errors.YumFutureDeprecationWarning, stacklevel=2)           
-@@ -2700,13 +3311,23 @@ class YumBase(depsolve.Depsolve):
+@@ -2700,13 +3310,23 @@ class YumBase(depsolve.Depsolve):
      
      def searchPackageProvides(self, args, callback=None,
                                callback_has_matchfor=False):
@@ -188632,7 +188709,7 @@ index 99039e0..9fb88d4 100644
              else:
                  isglob = True
                  canBeFile = misc.re_filename(arg)
-@@ -2723,7 +3344,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2723,7 +3343,7 @@ class YumBase(depsolve.Depsolve):
                  where = self.returnPackagesByDep(arg)
              else:
                  usedDepString = False
@@ -188641,7 +188718,7 @@ index 99039e0..9fb88d4 100644
              self.verbose_logger.log(logginglevels.DEBUG_1,
                 P_('Searching %d package', 'Searching %d packages', len(where)), len(where))
              
-@@ -2817,25 +3438,166 @@ class YumBase(depsolve.Depsolve):
+@@ -2817,25 +3437,166 @@ class YumBase(depsolve.Depsolve):
              
          return matches
  
@@ -188820,13 +188897,10 @@ index 99039e0..9fb88d4 100644
                  if uservisible:
                      if grp.user_visible:
                          installed.append(grp)
-@@ -2847,34 +3609,97 @@ class YumBase(depsolve.Depsolve):
+@@ -2847,34 +3608,97 @@ class YumBase(depsolve.Depsolve):
                          available.append(grp)
                  else:
                      available.append(grp)
--            
--        return sorted(installed), sorted(available)
--    
 +
 +        for evgrp in evgrps:
 +            if ievgrps is None:
@@ -188840,7 +188914,7 @@ index 99039e0..9fb88d4 100644
 +                einstalled.append(evgrp)
 +            else:
 +                eavailable.append(evgrp)
-+            
+             
 +        if igrps is None:
 +            igrps = {}
 +        if ievgrps is None:
@@ -188876,8 +188950,9 @@ index 99039e0..9fb88d4 100644
 +        if return_evgrps:
 +            return (sorted(installed), sorted(available),
 +                    sorted(einstalled), sorted(eavailable))
-+        return sorted(installed), sorted(available)
+         return sorted(installed), sorted(available)
      
+-    
      def groupRemove(self, grpid):
 -        """mark all the packages in this group to be removed"""
 -        
@@ -188928,7 +189003,7 @@ index 99039e0..9fb88d4 100644
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -2898,18 +3723,53 @@ class YumBase(depsolve.Depsolve):
+@@ -2898,18 +3722,53 @@ class YumBase(depsolve.Depsolve):
                              self.tsInfo.remove(txmbr.po.pkgtup)
          
          
@@ -188992,7 +189067,7 @@ index 99039e0..9fb88d4 100644
          txmbrs_used = []
          thesegroups = self.comps.return_groups(grpid)
       
-@@ -2920,12 +3780,18 @@ class YumBase(depsolve.Depsolve):
+@@ -2920,12 +3779,18 @@ class YumBase(depsolve.Depsolve):
          if group_package_types:
              package_types = group_package_types
  
@@ -189011,7 +189086,7 @@ index 99039e0..9fb88d4 100644
              pkgs = []
              if 'mandatory' in package_types:
                  pkgs.extend(thisgroup.mandatory_packages)
-@@ -2934,12 +3800,56 @@ class YumBase(depsolve.Depsolve):
+@@ -2934,12 +3799,56 @@ class YumBase(depsolve.Depsolve):
              if 'optional' in package_types:
                  pkgs.extend(thisgroup.optional_packages)
  
@@ -189069,7 +189144,7 @@ index 99039e0..9fb88d4 100644
                  except Errors.InstallError, e:
                      self.verbose_logger.debug(_('No package named %s available to be installed'),
                          pkg)
-@@ -2953,7 +3863,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2953,7 +3862,9 @@ class YumBase(depsolve.Depsolve):
                  group_conditionals = enable_group_conditionals
  
              count_cond_test = 0
@@ -189080,7 +189155,7 @@ index 99039e0..9fb88d4 100644
                  for condreq, cond in thisgroup.conditional_packages.iteritems():
                      if self.isPackageInstalled(cond):
                          try:
-@@ -2990,17 +3902,23 @@ class YumBase(depsolve.Depsolve):
+@@ -2990,17 +3901,23 @@ class YumBase(depsolve.Depsolve):
                          if cond not in self.tsInfo.conditionals:
                              self.tsInfo.conditionals[cond] = []
                          self.tsInfo.conditionals[cond].extend(pkgs)
@@ -189111,7 +189186,7 @@ index 99039e0..9fb88d4 100644
          
          if not self.comps.has_group(grpid):
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3008,7 +3926,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3008,7 +3925,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)
@@ -189121,7 +189196,7 @@ index 99039e0..9fb88d4 100644
          for thisgroup in thesegroups:
              thisgroup.selected = False
              
-@@ -3034,13 +3953,114 @@ class YumBase(depsolve.Depsolve):
+@@ -3034,13 +3952,114 @@ class YumBase(depsolve.Depsolve):
                          for pkg in self.tsInfo.conditionals.get(txmbr.name, []):
                              self.tsInfo.remove(pkg.pkgtup)
          
@@ -189242,7 +189317,7 @@ index 99039e0..9fb88d4 100644
          # look it up in the self.localPackages first:
          for po in self.localPackages:
              if po.pkgtup == pkgtup:
-@@ -3049,7 +4069,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3049,7 +4068,7 @@ class YumBase(depsolve.Depsolve):
          pkgs = self.pkgSack.searchPkgTuple(pkgtup)
  
          if len(pkgs) == 0:
@@ -189251,7 +189326,7 @@ index 99039e0..9fb88d4 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 +4085,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3065,13 +4084,21 @@ class YumBase(depsolve.Depsolve):
          return result
  
      def getInstalledPackageObject(self, pkgtup):
@@ -189278,7 +189353,7 @@ index 99039e0..9fb88d4 100644
              raise Errors.RpmDBError, _('Package tuple %s could not be found in rpmdb') % str(pkgtup)
  
          # Dito. FIXME from getPackageObject() for len() > 1 ... :)
-@@ -3079,9 +4107,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3079,9 +4106,11 @@ class YumBase(depsolve.Depsolve):
          return po
          
      def gpgKeyCheck(self):
@@ -189292,7 +189367,7 @@ index 99039e0..9fb88d4 100644
          gpgkeyschecked = self.conf.cachedir + '/.gpgkeyschecked.yum'
          if os.path.exists(gpgkeyschecked):
              return 1
-@@ -3106,9 +4136,13 @@ class YumBase(depsolve.Depsolve):
+@@ -3106,9 +4135,13 @@ class YumBase(depsolve.Depsolve):
              return 1
  
      def returnPackagesByDep(self, depstring):
@@ -189308,7 +189383,7 @@ index 99039e0..9fb88d4 100644
          if not depstring:
              return []
  
-@@ -3132,12 +4166,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3132,12 +4165,23 @@ class YumBase(depsolve.Depsolve):
                          raise Errors.YumBaseError, _('Invalid version flag from: %s') % str(depstring)
                      depflags = SYMBOLFLAGS[flagsymbol]
  
@@ -189335,7 +189410,7 @@ index 99039e0..9fb88d4 100644
          # we get all sorts of randomness here
          errstring = depstring
          if type(depstring) not in types.StringTypes:
-@@ -3149,16 +4194,22 @@ class YumBase(depsolve.Depsolve):
+@@ -3149,16 +4193,22 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _('No Package found for %s') % errstring
          
          ps = ListPackageSack(pkglist)
@@ -189362,7 +189437,7 @@ index 99039e0..9fb88d4 100644
          if not depstring:
              return []
  
-@@ -3182,14 +4233,53 @@ class YumBase(depsolve.Depsolve):
+@@ -3182,14 +4232,53 @@ class YumBase(depsolve.Depsolve):
                          raise Errors.YumBaseError, _('Invalid version flag from: %s') % str(depstring)
                      depflags = SYMBOLFLAGS[flagsymbol]
  
@@ -189418,7 +189493,7 @@ index 99039e0..9fb88d4 100644
          
          
          if len(pkglist) == 0:
-@@ -3198,14 +4288,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3198,14 +4287,23 @@ class YumBase(depsolve.Depsolve):
          if len(pkglist) == 1:
              return pkglist[0]
  
@@ -189448,7 +189523,7 @@ index 99039e0..9fb88d4 100644
          returnlist = []
          compatArchList = self.arch.get_arch_list(arch)
          multiLib = []
-@@ -3222,9 +4321,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3222,9 +4320,9 @@ class YumBase(depsolve.Depsolve):
                  singleLib.append(po)
                  
          # we now have three lists.  find the best package(s) of each
@@ -189461,7 +189536,7 @@ index 99039e0..9fb88d4 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 +4337,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3238,7 +4336,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:
@@ -189470,7 +189545,7 @@ index 99039e0..9fb88d4 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3246,7 +4345,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3246,7 +4344,7 @@ class YumBase(depsolve.Depsolve):
                  if single: returnlist.append(single)
          # similar for the non-multilib case
          elif single:
@@ -189479,7 +189554,7 @@ index 99039e0..9fb88d4 100644
              if best.arch == "noarch":
                  returnlist.append(no)
              else:
-@@ -3350,28 +4449,76 @@ class YumBase(depsolve.Depsolve):
+@@ -3350,28 +4448,76 @@ class YumBase(depsolve.Depsolve):
              done = True
  
              slow = next_func(slow)
@@ -189563,7 +189638,7 @@ index 99039e0..9fb88d4 100644
          try:
              txmbrs = self.groupRemove(group_string)
          except yum.Errors.GroupsError:
-@@ -3387,6 +4534,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3387,6 +4533,8 @@ class YumBase(depsolve.Depsolve):
          assert pattern[0] == '@'
          grpid = pattern[1:]
  
@@ -189572,7 +189647,7 @@ index 99039e0..9fb88d4 100644
          thesegroups = self.comps.return_groups(grpid)
          if not thesegroups:
              raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3398,7 +4547,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3398,7 +4546,11 @@ class YumBase(depsolve.Depsolve):
      def _minus_deselect(self, pattern):
          """ Remove things from the transaction, like kickstart. """
          assert pattern[0] == '-'
@@ -189585,7 +189660,7 @@ index 99039e0..9fb88d4 100644
  
          if pat and pat[0] == '@':
              pat = pat[1:]
-@@ -3437,14 +4590,87 @@ class YumBase(depsolve.Depsolve):
+@@ -3437,14 +4589,87 @@ class YumBase(depsolve.Depsolve):
              if flag not in self.tsInfo.probFilterFlags:
                  self.tsInfo.probFilterFlags.append(flag)
  
@@ -189679,7 +189754,7 @@ index 99039e0..9fb88d4 100644
          pkgs = []
          was_pattern = False
          if po:
-@@ -3464,9 +4690,14 @@ class YumBase(depsolve.Depsolve):
+@@ -3464,9 +4689,14 @@ class YumBase(depsolve.Depsolve):
                  if kwargs['pattern'] and kwargs['pattern'][0] == '@':
                      return self._at_groupinstall(kwargs['pattern'])
  
@@ -189694,7 +189769,7 @@ index 99039e0..9fb88d4 100644
                                                        ignore_case=False)
                  pkgs.extend(mypkgs)
                  # if we have anything left unmatched, let's take a look for it
-@@ -3477,20 +4708,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3477,20 +4707,12 @@ class YumBase(depsolve.Depsolve):
                      self.verbose_logger.debug(_('Checking for virtual provide or file-provide for %s'), 
                          arg)
  
@@ -189721,7 +189796,7 @@ index 99039e0..9fb88d4 100644
              else:
                  nevra_dict = self._nevra_kwarg_parse(kwargs)
  
-@@ -3499,6 +4722,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3499,6 +4721,8 @@ class YumBase(depsolve.Depsolve):
                       ver=nevra_dict['version'], rel=nevra_dict['release'])
                  self._add_not_found_a(pkgs, nevra_dict)
                  
@@ -189730,7 +189805,7 @@ index 99039e0..9fb88d4 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 +4802,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3577,17 +4801,21 @@ class YumBase(depsolve.Depsolve):
                      continue
              
              # make sure this shouldn't be passed to update:
@@ -189756,7 +189831,7 @@ index 99039e0..9fb88d4 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 +4829,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3600,23 +4828,23 @@ class YumBase(depsolve.Depsolve):
                      already_obs = pkgs[0]
  
                  if already_obs:
@@ -189787,7 +189862,7 @@ index 99039e0..9fb88d4 100644
                      continue
  
              # make sure we don't have a name.arch of this already installed
-@@ -3630,8 +4859,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3630,8 +4858,8 @@ class YumBase(depsolve.Depsolve):
                          found = True
                          break
                  if not found:
@@ -189798,7 +189873,7 @@ index 99039e0..9fb88d4 100644
                      tx_return.extend(txmbrs)
                      continue
  
-@@ -3719,19 +4948,47 @@ class YumBase(depsolve.Depsolve):
+@@ -3719,19 +4947,47 @@ class YumBase(depsolve.Depsolve):
          return txmbr
  
      def update(self, po=None, requiringPo=None, update_to=False, **kwargs):
@@ -189853,7 +189928,7 @@ index 99039e0..9fb88d4 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 +5022,15 @@ class YumBase(depsolve.Depsolve):
+@@ -3765,7 +5021,15 @@ class YumBase(depsolve.Depsolve):
                      if new is None:
                          continue
                      tx_return.extend(self.update(po=new))
@@ -189870,7 +189945,7 @@ index 99039e0..9fb88d4 100644
              return tx_return
  
          # complications
-@@ -3787,13 +5052,16 @@ class YumBase(depsolve.Depsolve):
+@@ -3787,13 +5051,16 @@ class YumBase(depsolve.Depsolve):
                  return self._minus_deselect(kwargs['pattern'])
  
              if kwargs['pattern'] and kwargs['pattern'][0] == '@':
@@ -189889,7 +189964,7 @@ index 99039e0..9fb88d4 100644
  
              if not instpkgs and not availpkgs:
                  depmatches = []
-@@ -3805,6 +5073,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3805,6 +5072,8 @@ class YumBase(depsolve.Depsolve):
                  except yum.Errors.YumBaseError, e:
                      self.logger.critical(_('%s') % e)
  
@@ -189898,7 +189973,7 @@ index 99039e0..9fb88d4 100644
                  if update_to:
                      availpkgs.extend(depmatches)
                  else:
-@@ -3816,9 +5086,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3816,9 +5085,12 @@ class YumBase(depsolve.Depsolve):
              try:
                  if update_to:
                      m = []
@@ -189912,7 +189987,7 @@ index 99039e0..9fb88d4 100644
                      m = self.pkgSack.returnNewestByNameArch(patterns=pats)
              except Errors.PackageSackError:
                  m = []
-@@ -3843,7 +5116,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3843,7 +5115,7 @@ class YumBase(depsolve.Depsolve):
                      availpkgs = self._compare_providers(availpkgs, requiringPo)
                      availpkgs = map(lambda x: x[0], availpkgs)
                  elif not availpkgs:
@@ -189921,7 +189996,7 @@ index 99039e0..9fb88d4 100644
         
          # for any thing specified
          # get the list of available pkgs matching it (or take the po)
-@@ -3879,6 +5152,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3879,6 +5151,7 @@ class YumBase(depsolve.Depsolve):
                      if obsoleting_pkg is None:
                          continue
                      obs_pkgs.append(obsoleting_pkg)
@@ -189929,7 +190004,7 @@ index 99039e0..9fb88d4 100644
                  for obsoleting_pkg in packagesNewestByName(obs_pkgs):
                      tx_return.extend(self.install(po=obsoleting_pkg))
              for available_pkg in availpkgs:
-@@ -3920,11 +5194,29 @@ class YumBase(depsolve.Depsolve):
+@@ -3920,11 +5193,29 @@ class YumBase(depsolve.Depsolve):
                      tx_return.append(txmbr)
                          
          for available_pkg in availpkgs:
@@ -189959,7 +190034,7 @@ index 99039e0..9fb88d4 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 +5277,18 @@ class YumBase(depsolve.Depsolve):
+@@ -3985,11 +5276,18 @@ class YumBase(depsolve.Depsolve):
          return tx_return
          
      def remove(self, po=None, **kwargs):
@@ -189983,7 +190058,7 @@ index 99039e0..9fb88d4 100644
          if not po and not kwargs:
              raise Errors.RemoveError, 'Nothing specified to remove'
          
-@@ -4008,6 +5307,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4008,6 +5306,10 @@ class YumBase(depsolve.Depsolve):
                      return self._at_groupremove(kwargs['pattern'])
  
                  (e,m,u) = self.rpmdb.matchPackageNames([kwargs['pattern']])
@@ -189994,7 +190069,7 @@ index 99039e0..9fb88d4 100644
                  pkgs.extend(e)
                  pkgs.extend(m)
                  if u:
-@@ -4018,6 +5321,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4018,6 +5320,10 @@ class YumBase(depsolve.Depsolve):
                      except yum.Errors.YumBaseError, e:
                          self.logger.critical(_('%s') % e)
                      
@@ -190005,7 +190080,7 @@ index 99039e0..9fb88d4 100644
                      if not depmatches:
                          arg = to_unicode(arg)
                          self.logger.critical(_('No Match for argument: %s') % to_unicode(arg))
-@@ -4055,17 +5362,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4055,17 +5361,19 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def installLocal(self, pkg, po=None, updateonly=False):
@@ -190035,7 +190110,7 @@ index 99039e0..9fb88d4 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 +5492,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4183,16 +5491,15 @@ class YumBase(depsolve.Depsolve):
          return tx_return
  
      def reinstallLocal(self, pkg, po=None):
@@ -190060,7 +190135,7 @@ index 99039e0..9fb88d4 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4215,13 +5523,29 @@ class YumBase(depsolve.Depsolve):
+@@ -4215,13 +5522,29 @@ class YumBase(depsolve.Depsolve):
          return self.reinstall(po=po)
  
      def reinstall(self, po=None, **kwargs):
@@ -190093,7 +190168,7 @@ index 99039e0..9fb88d4 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 +5564,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4240,10 +5563,11 @@ class YumBase(depsolve.Depsolve):
              # pkgs that are obsolete.
              old_conf_obs = self.conf.obsoletes
              self.conf.obsoletes = False
@@ -190107,7 +190182,7 @@ index 99039e0..9fb88d4 100644
              self.conf.obsoletes = old_conf_obs
              if len(members) == 0:
                  self.tsInfo.remove(item.pkgtup)
-@@ -4259,16 +5584,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4259,16 +5583,15 @@ class YumBase(depsolve.Depsolve):
          return tx_mbrs
          
      def downgradeLocal(self, pkg, po=None):
@@ -190132,7 +190207,7 @@ index 99039e0..9fb88d4 100644
          if not po:
              try:
                  po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4309,13 +5633,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4309,13 +5632,19 @@ class YumBase(depsolve.Depsolve):
          return False
          
      def downgrade(self, po=None, **kwargs):
@@ -190159,7 +190234,7 @@ index 99039e0..9fb88d4 100644
          if not po and not kwargs:
              raise Errors.DowngradeError, 'Nothing specified to downgrade'
  
-@@ -4397,6 +5727,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4397,6 +5726,10 @@ class YumBase(depsolve.Depsolve):
          # installed version. Indexed fromn the latest installed pkgtup.
          downgrade_apkgs = {}
          for pkg in sorted(apkgs):
@@ -190170,7 +190245,7 @@ index 99039e0..9fb88d4 100644
              na  = (pkg.name, pkg.arch)
  
              # Here we allow downgrades from .i386 => .noarch, or .i586 => .i386
-@@ -4421,6 +5755,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4421,6 +5754,9 @@ class YumBase(depsolve.Depsolve):
                  warned_nas.add(na)
                  continue
  
@@ -190180,7 +190255,7 @@ index 99039e0..9fb88d4 100644
              if pkg.verGE(lipkg):
                  if na not in warned_nas:
                      msg = _('Only Upgrade available on package: %s') % pkg
-@@ -4457,7 +5794,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4457,7 +5793,7 @@ class YumBase(depsolve.Depsolve):
          if e and v and r:
              evr = '%s:%s-%s' % (e, v, r)
          elif v and r:
@@ -190189,7 +190264,7 @@ index 99039e0..9fb88d4 100644
          elif e and v:
              evr = '%s:%s' % (e, v)
          elif v: # e and r etc. is just too weird to print
-@@ -4500,12 +5837,24 @@ class YumBase(depsolve.Depsolve):
+@@ -4500,12 +5836,24 @@ class YumBase(depsolve.Depsolve):
  
          return returndict
  
@@ -190217,7 +190292,7 @@ index 99039e0..9fb88d4 100644
          old_conf_obs = self.conf.obsoletes
          self.conf.obsoletes = False
          done = False
-@@ -4515,19 +5864,46 @@ class YumBase(depsolve.Depsolve):
+@@ -4515,19 +5863,46 @@ class YumBase(depsolve.Depsolve):
                      done = True
          for pkg in transaction.trans_data:
              if pkg.state == 'Downgrade':
@@ -190264,7 +190339,7 @@ index 99039e0..9fb88d4 100644
                  if self.install(pkgtup=pkg.pkgtup):
                      done = True
          for pkg in transaction.trans_data:
-@@ -4538,8 +5914,14 @@ class YumBase(depsolve.Depsolve):
+@@ -4538,8 +5913,14 @@ class YumBase(depsolve.Depsolve):
          return done
  
      def history_undo(self, transaction):
@@ -190281,7 +190356,7 @@ index 99039e0..9fb88d4 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 +5998,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4616,7 +5997,7 @@ class YumBase(depsolve.Depsolve):
  
          except urlgrabber.grabber.URLGrabError, e:
              raise Errors.YumBaseError(_('GPG key retrieval failed: ') +
@@ -190290,7 +190365,7 @@ index 99039e0..9fb88d4 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 +6031,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4649,7 +6030,7 @@ class YumBase(depsolve.Depsolve):
              keys_info = misc.getgpgkeyinfo(rawkey, multiple=True)
          except ValueError, e:
              raise Errors.YumBaseError(_('Invalid GPG Key from %s: %s') % 
@@ -190299,7 +190374,7 @@ index 99039e0..9fb88d4 100644
          keys = []
          for keyinfo in keys_info:
              thiskey = {}
-@@ -4674,39 +6056,49 @@ class YumBase(depsolve.Depsolve):
+@@ -4674,39 +6055,49 @@ class YumBase(depsolve.Depsolve):
              if pkgs:
                  pkgs = sorted(pkgs)[-1]
                  msg = (_('Importing %s key 0x%s:\n'
@@ -190367,7 +190442,7 @@ index 99039e0..9fb88d4 100644
          user_cb_fail = False
          for keyurl in keyurls:
              keys = self._retrievePublicKey(keyurl, repo)
-@@ -4725,7 +6117,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4725,7 +6116,9 @@ class YumBase(depsolve.Depsolve):
                      # Try installing/updating GPG key
                      self._getKeyImportMessage(info, keyurl)
                      rc = False
@@ -190378,7 +190453,7 @@ index 99039e0..9fb88d4 100644
                          rc = True
                          
                      # grab the .sig/.asc for the keyurl, if it exists
-@@ -4751,8 +6145,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4751,8 +6144,8 @@ class YumBase(depsolve.Depsolve):
                  ts = self.rpmdb.readOnlyTS()
                  result = ts.pgpImportPubkey(misc.procgpgkey(info['raw_key']))
                  if result != 0:
@@ -190389,7 +190464,7 @@ index 99039e0..9fb88d4 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
  
-@@ -4760,18 +6154,20 @@ class YumBase(depsolve.Depsolve):
+@@ -4760,18 +6153,20 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError, _("Didn't install any keys")
  
          if not key_installed:
@@ -190415,7 +190490,7 @@ index 99039e0..9fb88d4 100644
      
      def _getAnyKeyForRepo(self, repo, destdir, keyurl_list, is_cakey=False, callback=None):
          """
-@@ -4788,6 +6184,18 @@ class YumBase(depsolve.Depsolve):
+@@ -4788,6 +6183,18 @@ class YumBase(depsolve.Depsolve):
          """
  
          key_installed = False
@@ -190434,7 +190509,7 @@ index 99039e0..9fb88d4 100644
          user_cb_fail = False
          for keyurl in keyurl_list:
              keys = self._retrievePublicKey(keyurl, repo, getSig=not is_cakey)
-@@ -4819,8 +6227,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4819,8 +6226,11 @@ class YumBase(depsolve.Depsolve):
                  if not key_installed:
                      self._getKeyImportMessage(info, keyurl, keytype)
                      rc = False
@@ -190447,7 +190522,7 @@ index 99039e0..9fb88d4 100644
                      elif callback:
                          rc = callback({"repo": repo, "userid": info['userid'],
                                          "hexkeyid": info['hexkeyid'], "keyurl": keyurl,
-@@ -4835,7 +6246,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4835,7 +6245,8 @@ class YumBase(depsolve.Depsolve):
                  # Import the key
                  result = misc.import_key_to_pubring(info['raw_key'], info['hexkeyid'], gpgdir=destdir)
                  if not result:
@@ -190457,7 +190532,7 @@ index 99039e0..9fb88d4 100644
                  self.logger.info(_('Key imported successfully'))
                  key_installed = True
                  # write out the key id to imported_cakeys in the repos basedir
-@@ -4851,36 +6263,35 @@ class YumBase(depsolve.Depsolve):
+@@ -4851,36 +6262,35 @@ class YumBase(depsolve.Depsolve):
                              pass
  
          if not key_installed and user_cb_fail:
@@ -190510,7 +190585,7 @@ index 99039e0..9fb88d4 100644
          self._getAnyKeyForRepo(repo, repo.gpgcadir, repo.gpgcakey, is_cakey=True, callback=callback)
  
      def _limit_installonly_pkgs(self):
-@@ -4889,7 +6300,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4889,7 +6299,7 @@ class YumBase(depsolve.Depsolve):
              New in 3.2.24: Obey yumdb_info.installonly data. """
  
          def _sort_and_filter_installonly(pkgs):
@@ -190519,7 +190594,7 @@ index 99039e0..9fb88d4 100644
                  using the yumdb. """
              ret_beg = []
              ret_mid = []
-@@ -4917,6 +6328,10 @@ class YumBase(depsolve.Depsolve):
+@@ -4917,6 +6327,10 @@ class YumBase(depsolve.Depsolve):
  
          if self.conf.installonly_limit < 1 :
              return 
@@ -190530,7 +190605,7 @@ index 99039e0..9fb88d4 100644
              
          toremove = []
          #  We "probably" want to use either self.ts or self.rpmdb.ts if either
-@@ -4926,23 +6341,30 @@ class YumBase(depsolve.Depsolve):
+@@ -4926,23 +6340,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)
@@ -190569,7 +190644,7 @@ index 99039e0..9fb88d4 100644
              for po in installed:
                  if (po.version, po.release) == (cur_kernel_v, cur_kernel_r): 
                      # don't remove running
-@@ -4959,19 +6381,22 @@ class YumBase(depsolve.Depsolve):
+@@ -4959,19 +6380,22 @@ class YumBase(depsolve.Depsolve):
              txmbr.depends_on.append(rel)
  
      def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None):
@@ -190605,7 +190680,7 @@ index 99039e0..9fb88d4 100644
          
          if not callback:
              callback = callbacks.ProcessTransNoOutputCallback()
-@@ -5062,8 +6487,8 @@ class YumBase(depsolve.Depsolve):
+@@ -5062,8 +6486,8 @@ class YumBase(depsolve.Depsolve):
                  raise Errors.YumRPMCheckError, retmsgs
              retmsgs = [_('ERROR with transaction check vs depsolve:')]
              retmsgs.extend(msgs) 
@@ -190616,7 +190691,7 @@ index 99039e0..9fb88d4 100644
              raise Errors.YumRPMCheckError,retmsgs
          
          tsConf = {}
-@@ -5114,13 +6539,19 @@ class YumBase(depsolve.Depsolve):
+@@ -5114,13 +6538,19 @@ class YumBase(depsolve.Depsolve):
          return results
  
      def add_enable_repo(self, repoid, baseurls=[], mirrorlist=None, **kwargs):
@@ -190643,7 +190718,7 @@ index 99039e0..9fb88d4 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 +6598,15 @@ class YumBase(depsolve.Depsolve):
+@@ -5167,9 +6597,15 @@ class YumBase(depsolve.Depsolve):
  
      def setCacheDir(self, force=False, tmpdir=None, reuse=True,
                      suffix='/$basearch/$releasever'):
@@ -190662,7 +190737,7 @@ index 99039e0..9fb88d4 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 +6616,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5179,7 +6615,7 @@ class YumBase(depsolve.Depsolve):
          try:
              cachedir = misc.getCacheDir(tmpdir, reuse)
          except (IOError, OSError), e:
@@ -190671,7 +190746,7 @@ index 99039e0..9fb88d4 100644
              cachedir = None
              
          if cachedir is None:
-@@ -5190,6 +6627,8 @@ class YumBase(depsolve.Depsolve):
+@@ -5190,6 +6626,8 @@ class YumBase(depsolve.Depsolve):
              self.prerepoconf.cachedir = cachedir
          else:
              self.repos.setCacheDir(cachedir)
@@ -190680,7 +190755,7 @@ index 99039e0..9fb88d4 100644
          self.conf.cachedir = cachedir
          return True # We got a new cache dir
  
-@@ -5220,13 +6659,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5220,13 +6658,24 @@ class YumBase(depsolve.Depsolve):
          self.history.write_addon_data('config-repos', myrepos)
          
      def verify_plugins_cb(self, verify_package):
@@ -190708,7 +190783,7 @@ index 99039e0..9fb88d4 100644
          if self.tsInfo._unresolvedMembers:
              if auto:
                  self.logger.critical(_("Dependencies not solved. Will not save unresolved transaction."))
-@@ -5234,7 +6684,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5234,7 +6683,7 @@ class YumBase(depsolve.Depsolve):
              raise Errors.YumBaseError(_("Dependencies not solved. Will not save unresolved transaction."))
          
          if not filename:
@@ -190717,7 +190792,7 @@ index 99039e0..9fb88d4 100644
              fd,filename = tempfile.mkstemp(suffix='.yumtx', prefix=prefix)
              f = os.fdopen(fd, 'w')
          else:
-@@ -5244,13 +6694,17 @@ class YumBase(depsolve.Depsolve):
+@@ -5244,13 +6693,17 @@ class YumBase(depsolve.Depsolve):
          
          msg = "%s\n" % self.rpmdb.simpleVersion(main_only=True)[0]
          msg += "%s\n" % self.ts.getTsFlags()
@@ -190738,7 +190813,7 @@ index 99039e0..9fb88d4 100644
          msg += "%s\n" % len(self.tsInfo.getMembers())
          for txmbr in self.tsInfo.getMembers():
              msg += txmbr._dump()
-@@ -5260,42 +6714,84 @@ class YumBase(depsolve.Depsolve):
+@@ -5260,42 +6713,84 @@ class YumBase(depsolve.Depsolve):
          except (IOError, OSError), e:
              self._ts_save_file = None
              if auto:
@@ -190835,7 +190910,7 @@ index 99039e0..9fb88d4 100644
              if ignorerpm:
                  msg += _(" ignoring, as requested.")
                  self.logger.critical(_(msg))
-@@ -5318,8 +6814,17 @@ class YumBase(depsolve.Depsolve):
+@@ -5318,8 +6813,17 @@ class YumBase(depsolve.Depsolve):
          numrepos = int(data[2].strip())
          repos = []
          rindex=3+numrepos
@@ -190854,7 +190929,7 @@ index 99039e0..9fb88d4 100644
  
          # pkgs/txmbrs
          numpkgs = int(data[rindex].strip())
-@@ -5329,6 +6834,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5329,6 +6833,7 @@ class YumBase(depsolve.Depsolve):
          pkgcount = 0
          pkgprob = False
          curpkg = None
@@ -190862,7 +190937,7 @@ index 99039e0..9fb88d4 100644
          for l in data[pkgstart:]:
              l = l.rstrip()
              # our main txmbrs
-@@ -5356,6 +6862,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5356,6 +6861,7 @@ class YumBase(depsolve.Depsolve):
                      if not ignoremissing:
                          raise Errors.YumBaseError(msg)
                      else:
@@ -190870,7 +190945,7 @@ index 99039e0..9fb88d4 100644
                          self.logger.critical(msg)
                  else:
                      pkgcount += 1
-@@ -5432,12 +6939,18 @@ class YumBase(depsolve.Depsolve):
+@@ -5432,12 +6938,18 @@ class YumBase(depsolve.Depsolve):
          if pkgprob:
              msg = _("Transaction members, relations are missing or ts has been modified,")
              if ignoremissing:
@@ -190889,7 +190964,7 @@ index 99039e0..9fb88d4 100644
          return self.tsInfo.getMembers()
  
      def _remove_old_deps(self):
-@@ -5470,18 +6983,6 @@ class YumBase(depsolve.Depsolve):
+@@ -5470,18 +6982,6 @@ class YumBase(depsolve.Depsolve):
                      if requiring == required: # if they are self-requiring skip them
                          continue
                          
@@ -190908,7 +190983,7 @@ index 99039e0..9fb88d4 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 +7034,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5533,7 +7033,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
@@ -190933,7 +191008,7 @@ index 99039e0..9fb88d4 100644
                  visited[curpkg] = True
              all_leaves_visited = True
              leaves = curpkg.requiring_packages()
-@@ -5547,4 +7065,3 @@ class YumBase(depsolve.Depsolve):
+@@ -5547,4 +7064,3 @@ class YumBase(depsolve.Depsolve):
          # Debugging output
          self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has no user-installed revdeps."), pkg)
          return False
@@ -193400,10 +193475,10 @@ index 6d744c0..95c21bc 100644
          self.conflict = conflict # what the conflict was between them
 diff --git a/yum/drpm.py b/yum/drpm.py
 new file mode 100644
-index 0000000..42bf70e
+index 0000000..cc680cd
 --- /dev/null
 +++ b/yum/drpm.py
-@@ -0,0 +1,347 @@
+@@ -0,0 +1,351 @@
 +#  Integrated delta rpm support
 +#  Copyright 2013 Zdenek Pavlas
 +
@@ -193676,7 +193751,11 @@ index 0000000..42bf70e
 +                # done with drpm file, unlink when local
 +                if po.localpath.startswith(po.repo.pkgdir):
 +                    os.unlink(po.localpath)
-+                po.localpath = po.rpm.localpath # for --downloadonly
++                # rename the rpm if --downloadonly
++                if po.rpm.localpath.endswith('.tmp'):
++                    rpmfile = po.rpm.localpath.rsplit('.', 2)[0]
++                    os.rename(po.rpm.localpath, rpmfile)
++                    po.rpm.localpath = rpmfile
 +            num += 1
 +
 +            # when blocking, one is enough
@@ -196807,7 +196886,7 @@ index 31b1080..5055e64 100755
              tags += """ </tags>\n"""
              msg += tags
 diff --git a/yum/repos.py b/yum/repos.py
-index 3793bad..67ef1e4 100644
+index 3793bad..d5e50ac 100644
 --- a/yum/repos.py
 +++ b/yum/repos.py
 @@ -15,13 +15,14 @@
@@ -196945,11 +197024,12 @@ index 3793bad..67ef1e4 100644
 -            match = re.compile(fnmatch.translate(item)).match
 +            match = misc.compile_pattern(item.strip(), ignore_case)
              for name,repo in self.repos.items():
+-                if match(name):
 +                assert name == repo.id
-                 if match(name):
-                     result.append(repo)
-+                elif name_match and match(repo.name):
++                if match(name) or match(repo.ui_id):
 +                    result.append(repo)
++                elif name_match and match(repo.name):
+                     result.append(repo)
 +
          return result
          
@@ -197611,7 +197691,7 @@ index 4d7e36e..826ad62 100644
      @param     quotes: legal quoting characters
      @type      quotes: string
 diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
-index 4d89d83..d34f3a8 100644
+index 4d89d83..9ce5025 100644
 --- a/yum/transactioninfo.py
 +++ b/yum/transactioninfo.py
 @@ -34,6 +34,8 @@ import Errors
@@ -197781,6 +197861,15 @@ index 4d89d83..d34f3a8 100644
  
          if self.rpmdb.contains(po=txmbr.po):
              txmbr.reinstall = True
+@@ -478,7 +519,7 @@ class TransactionData:
+         return txmbr
+ 
+     def addDowngrade(self, po, oldpo):
+-        """adds a package as an downgrade takes a packages object and returns
++        """adds a package as a downgrade takes a packages object and returns
+            a pair of TransactionMember Objects"""
+ 
+         itxmbr = self.addErase(oldpo)
 @@ -489,6 +530,10 @@ class TransactionData:
          if not atxmbr: # Fail?
              self.remove(itxmbr.pkgtup)
@@ -199792,7 +199881,7 @@ index e5e9ece..35359e2 100644
          fo = None
  
 diff --git a/yumcommands.py b/yumcommands.py
-index 4dcbea7..291eae5 100644
+index 4dcbea7..8bba0c5 100644
 --- a/yumcommands.py
 +++ b/yumcommands.py
 @@ -13,6 +13,7 @@
@@ -199853,7 +199942,7 @@ index 4dcbea7..291eae5 100644
      if not base.gpgKeyCheck():
          for repo in base.repos.listEnabled():
              if (repo.gpgcheck or repo.repo_gpgcheck) and not repo.gpgkey:
-@@ -75,31 +87,122 @@ For more information contact your distribution or package provider.
+@@ -75,31 +87,117 @@ For more information contact your distribution or package provider.
                  raise cli.CliError
  
  def checkPackageArg(base, basecmd, extcmds):
@@ -199898,12 +199987,6 @@ index 4dcbea7..291eae5 100644
 +    :param extcmds: a list of arguments passed to *basecmd*
 +    :raises: :class:`cli.CliError`
 +    """
-+    if len(extcmds) < 2: # <repoid> install|remove [pkgs]
-+        base.logger.critical(
-+                _('Error: Need to pass a repoid. and command to %s') % basecmd)
-+        _err_mini_usage(base, basecmd)
-+        raise cli.CliError
-+
 +    repos = base.repos.findRepos(extcmds[0], name_match=True, ignore_case=True)
 +    if not repos:
 +        base.logger.critical(
@@ -199925,6 +200008,7 @@ index 4dcbea7..291eae5 100644
 +        base.repos.enableRepo(repos[0].id)
 +        base.verbose_logger.info(
 +                _('Repo %s has been automatically enabled.') % repos[0].ui_id)
++    return repos[0].id
 +
 +
  def checkItemArg(base, basecmd, extcmds):
@@ -199976,7 +200060,7 @@ index 4dcbea7..291eae5 100644
  
      for cmd in extcmds:
          if cmd not in VALID_ARGS:
-@@ -108,12 +211,14 @@ def checkCleanArg(base, basecmd, extcmds):
+@@ -108,12 +206,14 @@ def checkCleanArg(base, basecmd, extcmds):
              raise cli.CliError
  
  def checkShellArg(base, basecmd, extcmds):
@@ -199997,7 +200081,7 @@ index 4dcbea7..291eae5 100644
      """
      if len(extcmds) == 0:
          base.verbose_logger.debug(_("No argument to shell"))
-@@ -133,10 +238,12 @@ def checkShellArg(base, basecmd, extcmds):
+@@ -133,10 +233,12 @@ def checkShellArg(base, basecmd, extcmds):
          raise cli.CliError
  
  def checkEnabledRepo(base, possible_local_files=[]):
@@ -200013,7 +200097,7 @@ index 4dcbea7..291eae5 100644
      """
      if base.repos.listEnabled():
          return
-@@ -145,6 +252,11 @@ def checkEnabledRepo(base, possible_local_files=[]):
+@@ -145,6 +247,11 @@ def checkEnabledRepo(base, possible_local_files=[]):
          if lfile.endswith(".rpm") and os.path.exists(lfile):
              return
  
@@ -200025,7 +200109,7 @@ index 4dcbea7..291eae5 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 +259,296 @@ def checkEnabledRepo(base, possible_local_files=[]):
      raise cli.CliError
  
  class YumCommand:
@@ -200348,7 +200432,7 @@ index 4dcbea7..291eae5 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):
+@@ -289,22 +579,62 @@ def _list_cmd_calc_columns(base, ypl):
      return (-columns[0], -columns[1], -columns[2])
  
  class InfoCommand(YumCommand):
@@ -200418,7 +200502,7 @@ index 4dcbea7..291eae5 100644
              update_pkgs = {}
              inst_pkgs   = {}
              local_pkgs  = {}
-@@ -341,6 +676,7 @@ class InfoCommand(YumCommand):
+@@ -341,6 +671,7 @@ class InfoCommand(YumCommand):
                          local_pkgs[(po.name, po.arch)] = po
  
              # Output the packages:
@@ -200426,7 +200510,7 @@ index 4dcbea7..291eae5 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):
+@@ -348,7 +679,9 @@ class InfoCommand(YumCommand):
              rip = base.listPkgs(ypl.installed, _('Installed Packages'), basecmd,
                                  highlight_na=update_pkgs, columns=columns,
                                  highlight_modes={'>' : clio, '<' : clin,
@@ -200436,7 +200520,7 @@ index 4dcbea7..291eae5 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 +689,7 @@ class InfoCommand(YumCommand):
              rap = base.listPkgs(ypl.available, _('Available Packages'), basecmd,
                                  highlight_na=inst_pkgs, columns=columns,
                                  highlight_modes={'<' : clau, '>' : clad,
@@ -200444,7 +200528,7 @@ index 4dcbea7..291eae5 100644
                                                   '=' : clar, 'not in' : clai})
              rep = base.listPkgs(ypl.extras, _('Extra Packages'), basecmd,
                                  columns=columns)
-@@ -374,7 +713,7 @@ class InfoCommand(YumCommand):
+@@ -374,7 +708,7 @@ class InfoCommand(YumCommand):
                  for obtup in sorted(ypl.obsoletesTuples,
                                      key=operator.itemgetter(0)):
                      base.updatesObsoletesList(obtup, 'obsoletes',
@@ -200453,7 +200537,7 @@ index 4dcbea7..291eae5 100644
              else:
                  rop = base.listPkgs(ypl.obsoletes, _('Obsoleting Packages'),
                                      basecmd, columns=columns)
-@@ -389,45 +728,160 @@ class InfoCommand(YumCommand):
+@@ -389,45 +723,160 @@ class InfoCommand(YumCommand):
              return 0, []
  
      def needTs(self, base, basecmd, extcmds):
@@ -200619,7 +200703,7 @@ index 4dcbea7..291eae5 100644
          return True
  
   
-@@ -436,18 +890,31 @@ class GroupsCommand(YumCommand):
+@@ -436,18 +885,31 @@ class GroupsCommand(YumCommand):
  
      direct_commands = {'grouplist'    : 'list',
                         'groupinstall' : 'install',
@@ -200652,7 +200736,7 @@ index 4dcbea7..291eae5 100644
          return _("Display, or use, the groups information")
      
      def _grp_setup_doCommand(self, base):
-@@ -459,7 +926,7 @@ class GroupsCommand(YumCommand):
+@@ -459,7 +921,7 @@ class GroupsCommand(YumCommand):
          except yum.Errors.GroupsError:
              return 1, [_('No Groups on which to run command')]
          except yum.Errors.YumBaseError, e:
@@ -200661,7 +200745,7 @@ index 4dcbea7..291eae5 100644
  
      def _grp_cmd(self, basecmd, extcmds):
          if basecmd in self.direct_commands:
-@@ -470,6 +937,10 @@ class GroupsCommand(YumCommand):
+@@ -470,6 +932,10 @@ class GroupsCommand(YumCommand):
          else:
              cmd = 'summary'
  
@@ -200672,7 +200756,7 @@ index 4dcbea7..291eae5 100644
          remap = {'update' : 'upgrade',
                   'erase' : 'remove',
                   'mark-erase' : 'mark-remove',
-@@ -479,32 +950,86 @@ class GroupsCommand(YumCommand):
+@@ -479,32 +945,86 @@ class GroupsCommand(YumCommand):
          return cmd, extcmds
  
      def doCheck(self, base, basecmd, extcmds):
@@ -200769,7 +200853,7 @@ index 4dcbea7..291eae5 100644
          cmd, extcmds = self._grp_cmd(basecmd, extcmds)
  
          self._grp_setup_doCommand(base)
-@@ -514,140 +1039,573 @@ class GroupsCommand(YumCommand):
+@@ -514,140 +1034,573 @@ class GroupsCommand(YumCommand):
          if cmd == 'list':
              return base.returnGroupLists(extcmds)
  
@@ -201218,9 +201302,13 @@ index 4dcbea7..291eae5 100644
 +        """
          return False
  
+-class ProvidesCommand(YumCommand):
+-    def getNames(self):
+-        return ['provides', 'whatprovides']
 +    def cacheRequirement(self, base, basecmd, extcmds):
 +        """Return the cache requirements for the remote repos.
-+
+ 
+-    def getUsage(self):
 +        :param base: a :class:`yum.Yumbase` object
 +        :param basecmd: the name of the command
 +        :param extcmds: a list of arguments passed to *basecmd*
@@ -201229,20 +201317,20 @@ index 4dcbea7..291eae5 100644
 +        return 'read-only:past'
 +
 +
- class ProvidesCommand(YumCommand):
++class ProvidesCommand(YumCommand):
 +    """A class containing methods needed by the cli to execute the
 +    provides command.
 +    """
 +
-     def getNames(self):
++    def getNames(self):
 +        """Return a list containing the names of this command.  This
 +        command can be called from the command line by using any of these names.
 +
 +        :return: a list containing the names of this command
 +        """
-         return ['provides', 'whatprovides']
- 
-     def getUsage(self):
++        return ['provides', 'whatprovides']
++
++    def getUsage(self):
 +        """Return a usage string for this command.
 +
 +        :return: a usage string for this command
@@ -201368,7 +201456,7 @@ index 4dcbea7..291eae5 100644
                  ypl.obsoletes = typl.obsoletes
                  ypl.obsoletesTuples = typl.obsoletesTuples
  
-@@ -673,164 +1631,474 @@ class CheckUpdateCommand(YumCommand):
+@@ -673,164 +1626,474 @@ class CheckUpdateCommand(YumCommand):
                  for obtup in sorted(ypl.obsoletesTuples,
                                      key=operator.itemgetter(0)):
                      base.updatesObsoletesList(obtup, 'obsoletes',
@@ -201874,7 +201962,7 @@ index 4dcbea7..291eae5 100644
          def _repo_size(repo):
              ret = 0
              for pkg in repo.sack.returnPackages():
-@@ -838,12 +2106,9 @@ class RepoListCommand(YumCommand):
+@@ -838,12 +2101,9 @@ class RepoListCommand(YumCommand):
              return base.format_number(ret)
  
          def _repo_match(repo, patterns):
@@ -201889,7 +201977,7 @@ index 4dcbea7..291eae5 100644
                      return True
              return False
  
-@@ -857,7 +2122,10 @@ class RepoListCommand(YumCommand):
+@@ -857,7 +2117,10 @@ class RepoListCommand(YumCommand):
              arg = 'enabled'
          extcmds = map(lambda x: x.lower(), extcmds)
  
@@ -201901,7 +201989,7 @@ index 4dcbea7..291eae5 100644
          if arg != 'disabled' or extcmds:
              try:
                  # Setup so len(repo.sack) is correct
-@@ -866,6 +2134,13 @@ class RepoListCommand(YumCommand):
+@@ -866,6 +2129,13 @@ class RepoListCommand(YumCommand):
              except yum.Errors.RepoError:
                  if verbose:
                      raise
@@ -201915,7 +202003,7 @@ index 4dcbea7..291eae5 100644
  
          repos = base.repos.repos.values()
          repos.sort()
-@@ -924,111 +2199,113 @@ class RepoListCommand(YumCommand):
+@@ -924,111 +2194,113 @@ class RepoListCommand(YumCommand):
                  ui_enabled = dhibeg + _('disabled') + hiend
                  ui_endis_wid = utf8_width(_('disabled'))
  
@@ -202125,7 +202213,7 @@ index 4dcbea7..291eae5 100644
  
          if not verbose and cols:
              #  Work out the first (id) and last (enabled/disalbed/count),
-@@ -1088,21 +2365,64 @@ class RepoListCommand(YumCommand):
+@@ -1088,21 +2360,64 @@ class RepoListCommand(YumCommand):
          return 0, ['repolist: ' +to_unicode(locale.format("%d", tot_num, True))]
  
      def needTs(self, base, basecmd, extcmds):
@@ -202190,7 +202278,7 @@ index 4dcbea7..291eae5 100644
          if len(extcmds) == 0:
              base.usage()
              raise cli.CliError
-@@ -1147,82 +2467,230 @@ class HelpCommand(YumCommand):
+@@ -1147,82 +2462,230 @@ class HelpCommand(YumCommand):
          return help_output
  
      def doCommand(self, base, basecmd, extcmds):
@@ -202389,11 +202477,12 @@ index 4dcbea7..291eae5 100644
          return ['version']
  
      def getUsage(self):
+-        return "[all|installed|available]"
 +        """Return a usage string for this command.
 +
 +        :return: a usage string for this command
 +        """
-         return "[all|installed|available]"
++        return "[all|installed|available]"
  
      def getSummary(self):
 +        """Return a one line summary of this command.
@@ -202403,7 +202492,6 @@ index 4dcbea7..291eae5 100644
          return _("Display a version for the machine and/or available repos.")
  
      def doCommand(self, base, basecmd, extcmds):
--        vcmd = 'installed'
 +        """Execute this command.
 +
 +        :param base: a :class:`yum.Yumbase` object
@@ -202417,7 +202505,7 @@ index 4dcbea7..291eae5 100644
 +            1 = we've errored, exit with error string
 +            2 = we've got work yet to do, onto the next stage
 +        """
-+        vcmd = 'installed'
+         vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
 +        if vcmd in ('grouplist', 'groupinfo',
@@ -202431,7 +202519,7 @@ index 4dcbea7..291eae5 100644
  
          def _append_repos(cols, repo_data):
              for repoid in sorted(repo_data):
-@@ -1264,7 +2732,7 @@ class VersionCommand(YumCommand):
+@@ -1264,7 +2727,7 @@ class VersionCommand(YumCommand):
  
          if vcmd == 'groupinfo':
              for group in groups:
@@ -202440,7 +202528,7 @@ index 4dcbea7..291eae5 100644
                      continue
                  print _(" Group   :"), group
                  print _(" Packages:")
-@@ -1284,11 +2752,35 @@ class VersionCommand(YumCommand):
+@@ -1284,11 +2747,35 @@ class VersionCommand(YumCommand):
  
              return 0, ['version groupinfo']
  
@@ -202477,7 +202565,7 @@ index 4dcbea7..291eae5 100644
                  data = base.rpmdb.simpleVersion(not verbose, groups=groups)
                  lastdbv = base.history.last()
                  if lastdbv is not None:
-@@ -1302,15 +2794,14 @@ class VersionCommand(YumCommand):
+@@ -1302,15 +2789,14 @@ class VersionCommand(YumCommand):
                  if groups:
                      for grp in sorted(data[2]):
                          if (vcmd.startswith("group-") and
@@ -202496,7 +202584,7 @@ index 4dcbea7..291eae5 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 +2811,12 @@ class VersionCommand(YumCommand):
+@@ -1320,14 +2806,12 @@ class VersionCommand(YumCommand):
                  if groups:
                      for grp in sorted(data[2]):
                          if (vcmd.startswith("group-") and
@@ -202512,7 +202600,7 @@ index 4dcbea7..291eae5 100644
  
          data = {'rid' : {}, 'ver' : {}}
          for (rid, ver) in cols:
-@@ -1344,6 +2833,14 @@ class VersionCommand(YumCommand):
+@@ -1344,6 +2828,14 @@ class VersionCommand(YumCommand):
          return 0, ['version']
  
      def needTs(self, base, basecmd, extcmds):
@@ -202527,7 +202615,7 @@ index 4dcbea7..291eae5 100644
          vcmd = 'installed'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1352,25 +2849,74 @@ class VersionCommand(YumCommand):
+@@ -1352,25 +2844,74 @@ class VersionCommand(YumCommand):
              return True
          return vcmd in ('available', 'all', 'group-available', 'group-all')
  
@@ -202603,7 +202691,7 @@ index 4dcbea7..291eae5 100644
              return 2, ["Repeating transaction %u" % (old.tid,)]
  
      def _hcmd_undo(self, base, extcmds):
-@@ -1426,12 +2972,57 @@ class HistoryCommand(YumCommand):
+@@ -1426,12 +2967,57 @@ class HistoryCommand(YumCommand):
      def _hcmd_new(self, base, extcmds):
          base.history._create_db_file()
  
@@ -202662,7 +202750,7 @@ index 4dcbea7..291eae5 100644
          if extcmds and extcmds[0] not in cmds:
              base.logger.critical(_('Invalid history sub-command, use: %s.'),
                                   ", ".join(cmds))
-@@ -1444,6 +3035,19 @@ class HistoryCommand(YumCommand):
+@@ -1444,6 +3030,19 @@ class HistoryCommand(YumCommand):
              raise cli.CliError
  
      def doCommand(self, base, basecmd, extcmds):
@@ -202682,7 +202770,7 @@ index 4dcbea7..291eae5 100644
          vcmd = 'list'
          if extcmds:
              vcmd = extcmds[0]
-@@ -1468,29 +3072,88 @@ class HistoryCommand(YumCommand):
+@@ -1468,29 +3067,88 @@ class HistoryCommand(YumCommand):
              ret = self._hcmd_rollback(base, extcmds)
          elif vcmd == 'new':
              ret = self._hcmd_new(base, extcmds)
@@ -202771,7 +202859,7 @@ index 4dcbea7..291eae5 100644
          chkcmd = 'all'
          if extcmds:
              chkcmd = extcmds
-@@ -1505,33 +3168,1123 @@ class CheckRpmdbCommand(YumCommand):
+@@ -1505,33 +3163,1128 @@ class CheckRpmdbCommand(YumCommand):
          return rc, ['%s %s' % (basecmd, chkcmd)]
  
      def needTs(self, base, basecmd, extcmds):
@@ -203113,10 +203201,15 @@ index 4dcbea7..291eae5 100644
 +        :param basecmd: the name of the command
 +        :param extcmds: the command line arguments passed to *basecmd*
 +        """
-+        checkRootUID(base)
++        if len(extcmds) < 2: # <repoid> install|remove [pkgs]
++            base.logger.critical(
++                    _('Error: Need to pass a repoid. and command to %s') % basecmd)
++            _err_mini_usage(base, basecmd)
++            raise cli.CliError
++        if extcmds[1] not in ('info', 'list'):
++            checkRootUID(base)
 +        checkGPGKey(base)
-+        checkRepoPackageArg(base, basecmd, extcmds)
-+        checkEnabledRepo(base, extcmds)
++        self.repoid = checkRepoPackageArg(base, basecmd, extcmds)
 +
 +    def doCommand(self, base, basecmd, extcmds):
 +        """Execute this command.
@@ -203137,7 +203230,7 @@ index 4dcbea7..291eae5 100644
 +            for txmbr in txmbrs:
 +                txmbr.repopkg = repoid
 +
-+        repoid = extcmds[0]
++        repoid = self.repoid
 +        cmd = extcmds[1]
 +        args = extcmds[2:]
 +        noargs = False
diff --git a/yum.spec b/yum.spec
index fbd954c..19a75bf 100644
--- a/yum.spec
+++ b/yum.spec
@@ -60,7 +60,7 @@ BuildRequires: bash-completion
 Summary: RPM package installer/updater/manager
 Name: yum
 Version: 3.4.3
-Release: 131%{?dist}
+Release: 132%{?dist}
 License: GPLv2+
 Group: System Environment/Base
 Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz
@@ -444,6 +444,16 @@ exit 0
 %endif
 
 %changelog
+* Wed Jan 22 2014 Valentina Mukhamedzhanova <vmukhame at redhat.com> - 3.4.3-132
+- yum-cron: EmailEmitter failure should not be fatal. BZ 1055042
+- yum-cron: Add a retry loop around doLock().
+- _set_repos_cache_req(): Handle missing cachedir. BZ 1044080
+- repo-pkgs: Fix repoid parsing. BZ 1055132.
+- Fix bash completion for 'autoremove'
+- downloadonly: unlink .tmp files on ctrl-c. BZ 1045806
+- repo-pkgs <repoid> info|list shouldn't require root UID.
+- doPackageLists(repoid=<repoid>): filter 2nd ipkg lookup. BZ 1056489
+
 * Thu Jan 16 2014 Ville Skyttä <ville.skytta at iki.fi> - 3.4.3-131
 - Drop INSTALL from docs.
 


More information about the scm-commits mailing list