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