This should be safe to go in for 3.2.27, as it's an entirely self
contained command ... I've tried it here going on multiple directions,
and it WMF(tm).
---
 cli.py         |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 yumcommands.py |   25 ++++++++++++++++++++++
 2 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/cli.py b/cli.py
index f5ed53d..584dcf1 100644
--- a/cli.py
+++ b/cli.py
@@ -100,6 +100,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
         self.registerCommand(yumcommands.VersionCommand())
         self.registerCommand(yumcommands.HistoryCommand())
         self.registerCommand(yumcommands.CheckRpmdbCommand())
+        self.registerCommand(yumcommands.DistroSyncCommand())
 
     def registerCommand(self, command):
         for name in command.getNames():
@@ -649,6 +650,68 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
         else:
             return 0, [_('No Packages marked for Update')]
 
+    def distroSyncPkgs(self, userlist):
+        """ This does either upgrade/downgrade, depending on if the latest
+            installed version is older or newer. We allow "selection" but not
+            local packages (use tmprepo, or something). """
+
+        dupdates = []
+        ipkgs = {}
+        iapkgs = {}
+        for pkg in sorted(self.rpmdb.returnPackages(patterns=userlist)):
+            ipkgs[pkg.name] = pkg
+            iapkgs.setdefault(pkg.name, set()).add(pkg)
+
+        obsoletes = []
+        if self.conf.obsoletes:
+            obsoletes = self.up.getObsoletesTuples(newest=1)
+
+        for (obsoleting, installed) in obsoletes:
+            if installed[0] not in ipkgs:
+                continue
+            dupdates.extend(self.update(pkgtup=installed))
+        for (obsoleting, installed) in obsoletes:
+            if installed[0] not in ipkgs:
+                continue
+            del ipkg[installed[0]]
+
+        apkgs = {}
+        for pkg in self.pkgSack.returnNewestByName():
+            if pkg.name not in ipkgs:
+                continue
+            apkgs[pkg.name] = pkg
+
+        for ipkgname in ipkgs:
+            if ipkgname not in apkgs:
+                continue
+
+            ipkg = ipkgs[ipkgname]
+            apkg = apkgs[ipkgname]
+            if ipkg.verEQ(apkg):
+                continue
+            if self.allowedMultipleInstalls(apkg):
+                found = False
+                for napkg in self.rpmdb.searchNames([apkg.name]):
+                    if napkg.verEQ(apkg):
+                        found = True
+                    elif napkg.verGT(apkg):
+                        dupdates.extend(self.remove(po=napkg))
+                if found:
+                    continue
+                dupdates.extend(self.install(pattern=ipkg.name))
+            elif ipkg.verLT(apkg):
+                n,a,e,v,r = apkg.pkgtup
+                dupdates.extend(self.update(name=n, epoch=e, ver=v, rel=r))
+            else:
+                n,a,e,v,r = apkg.pkgtup
+                dupdates.extend(self.downgrade(name=n, epoch=e, ver=v, rel=r))
+
+        if dupdates:
+            msg = _('%d packages marked for Distribution Synchronization') % 
len(dupdates)
+            return 2, [msg]
+        else:
+            return 0, [_('No Packages marked for Distribution 
Synchronization')]
+
     def erasePkgs(self, userlist):
         """take user commands and populate a transaction wrapper with packages
            to be erased/removed"""
diff --git a/yumcommands.py b/yumcommands.py
index 35bd97c..67989ee 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -205,6 +205,31 @@ class UpdateCommand(YumCommand):
         except yum.Errors.YumBaseError, e:
             return 1, [str(e)]
 
+class DistroSyncCommand(YumCommand):
+    def getNames(self):
+        return ['distribution-synchronization', 'distro-sync',
+                'distribution-update', 'distro-update',
+                'distribution-upgrade', 'distro-upgrade']
+
+    def getUsage(self):
+        return _("[PACKAGE...]")
+
+    def getSummary(self):
+        return _("Synchronize installed packages to the latest available 
versions")
+
+    def doCheck(self, base, basecmd, extcmds):
+        checkRootUID(base)
+        checkGPGKey(base)
+
+    def doCommand(self, base, basecmd, extcmds):
+        self.doneCommand(base, _("Setting up Distribution Synchronization 
Process"))
+        try:
+            if not basecmd.endswith('-update'):
+                base.conf.obsoletes = 1
+            return base.distroSyncPkgs(extcmds)
+        except yum.Errors.YumBaseError, e:
+            return 1, [str(e)]
+
 def _add_pkg_simple_list_lens(data, pkg, indent=''):
     """ Get the length of each pkg's column. Add that to data.
         This "knows" about simpleList and printVer. """
-- 
1.6.6

_______________________________________________
Yum-devel mailing list
Yum-devel@lists.baseurl.org
http://lists.baseurl.org/mailman/listinfo/yum-devel

Reply via email to