#! /usr/bin/python -tt # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # # Copyright Red Hat Inc. 2007, 2008 # # Author: James Antill # # This makes an "excludes" that works in a similar way to up2date, Ie. it only # does an actual exclude to the "update" and "list updates" commands but it # also prints information about what it is doing. # # Examples: # # yum list updates # yum update # yum --force-update update import yum from yum.plugins import TYPE_INTERACTIVE import fnmatch requires_api_version = '2.5' plugin_type = (TYPE_INTERACTIVE,) def fd_should_filter_pkg(opts, pkg, pats): """ Do the package filtering for. """ for pat in pats: if fnmatch.fnmatch(pkg.name, pat): return True return False from yum import config def config_hook(conduit): config.StartupConf.skip_packages = config.ListOption([]) parser = conduit.getOptParser() parser.add_option('--force-updates', action="store_true", help='For updates regardless of skip_packages config.') def fd_check_func_enter(conduit): """ Stuff we need to do in both list and update modes. """ opts, args = conduit.getCmdLine() ret = None # Quick match, so we don't do lots of work when nothing has been specified ndata = (opts.force_updates or not len(conduit._base.conf.skip_packages)) if len(args) >= 1: if (args[0] in ["update", "upgrade", "install"]): ret = {"skip": ndata, "list_cmd": False} if (args[0] in ["check-update"]): # Pretend it's: list updates ret = {"skip": ndata, "list_cmd": True} if (len(args) >= 2 and args[0] in ["list", "info"] and args[1] == "updates"): ret = {"skip": ndata, "list_cmd": True} if ret: return (opts, ret) return (opts, {"skip": True, "list_cmd": False, "msg": True}) def fd_cmdline_splitArg(seq): """ Split all strings in seq, at "," and whitespace. Returns a new list. """ ret = [] for arg in seq: ret.extend(arg.replace(",", " ").split()) return ret def exclude_hook(conduit): ''' Yum Plugin Exclude Hook: up2date compat. excludes ''' opts, info = fd_check_func_enter(conduit) if info["skip"]: return if not info["list_cmd"]: return conduit.info(2, 'Listing skipped packages') skip_pats = fd_cmdline_splitArg(conduit._base.conf.skip_packages) def fd_del_pkg(pkg): """ Deletes a package within a list updates. """ conduit.info(2, " Skipping %s from %s" % (pkg, pkg.repoid)) conduit.delPackage(pkg) data = conduit._base.doPackageLists(pkgnarrow="updates") pkgs = data.updates del data done = False done_msg = ("%s Skipping packages %s\n %s" % ('=' * 25, '=' * 25,"Use the --force-update option to disable")) for pkg in pkgs: if fd_should_filter_pkg(opts, pkg, skip_pats): if not done: conduit.info(2, done_msg) done = True fd_del_pkg(pkg) def preresolve_hook(conduit): ''' Yum Plugin PreResolve Hook: up2date compat. excludes ''' opts, info = fd_check_func_enter(conduit) if info["skip"]: return if info["list_cmd"]: return conduit.info(2, 'Skipped packages') skip_pats = fd_cmdline_splitArg(conduit._base.conf.skip_packages) def fd_del_pkg(tspkg): """ Deletes a package within a transaction. """ conduit.info(2, " Skipping %s from %s" % (tspkg.po, tspkg.po.repoid)) tsinfo.remove(tspkg.pkgtup) tsinfo = conduit.getTsInfo() tspkgs = tsinfo.getMembers() done = False done_msg = ("%s Skipping packages %s\n %s" % ('=' * 25, '=' * 25,"Use the --force-update option to disable")) for tspkg in tspkgs: if fd_should_filter_pkg(opts, tspkg.po, skip_pats): if not done: conduit.info(2, done_msg) done = True fd_del_pkg(tspkg)