[yum-git] 2 commits - plugins/filter-data plugins/security yum-utils.spec
James Antill
james at linux.duke.edu
Fri Feb 1 21:25:56 UTC 2008
plugins/filter-data/filter-data.conf | 2
plugins/filter-data/filter-data.py | 393 +++++++++++++++++++++++++++++++++++
plugins/security/security.py | 2
yum-utils.spec | 27 ++
4 files changed, 420 insertions(+), 4 deletions(-)
New commits:
commit af1e791560078899b286d32604b2c85c96869acb
Author: James Antill <james at and.org>
Date: Fri Feb 1 16:25:52 2008 -0500
Add upgrade as a valid command to security
diff --git a/plugins/security/security.py b/plugins/security/security.py
index b7e02cb..fbf4852 100755
--- a/plugins/security/security.py
+++ b/plugins/security/security.py
@@ -336,7 +336,7 @@ def ysp_check_func_enter(conduit):
if len(args):
if (args[0] == "check-update"):
ret = {"skip": ndata, "list_cmd": True}
- if (args[0] == "update"):
+ if (args[0] in ["update", "upgrade"]):
ret = {"skip": ndata, "list_cmd": False}
if (args[0] == "list-sec") or (args[0] == "list-security"):
return (opts, {"skip": True, "list_cmd": True})
commit 492ce8cd8b31df7ff66274263d86b50794ab0944
Author: James Antill <james at and.org>
Date: Fri Feb 1 16:25:38 2008 -0500
The compliment to the list-data plugin, allows you to filter packages based
on arbitrary package data.
diff --git a/plugins/filter-data/filter-data.conf b/plugins/filter-data/filter-data.conf
new file mode 100644
index 0000000..8e4d76c
--- /dev/null
+++ b/plugins/filter-data/filter-data.conf
@@ -0,0 +1,2 @@
+[main]
+enabled=1
diff --git a/plugins/filter-data/filter-data.py b/plugins/filter-data/filter-data.py
new file mode 100644
index 0000000..a18e1e5
--- /dev/null
+++ b/plugins/filter-data/filter-data.py
@@ -0,0 +1,393 @@
+#! /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 <james.antill at redhat.com>
+#
+# This is the compliment to the list-data plugin, allowing you to filter on
+# any of the information given in that plugin.
+#
+# Examples:
+#
+# yum --filter-groups='App*/Sys*' list updates
+
+import yum
+from yum.plugins import TYPE_INTERACTIVE
+
+import fnmatch
+
+# For baseurl
+import urlparse
+
+
+requires_api_version = '2.5'
+plugin_type = (TYPE_INTERACTIVE,)
+
+
+fd__unknown = lambda x: x
+fd__max = 9999999999999
+def fd__get_data(pkg, attr, strip=True):
+ if not hasattr(pkg, attr):
+ return fd__unknown
+
+ val = getattr(pkg, attr)
+ if val is None:
+ return fd__unknown
+ if type(val) == type([]):
+ return fd__unknown
+
+ tval = str(val).strip()
+ if tval == "":
+ return fd__unknown
+
+ if strip:
+ return tval
+
+ return val
+
+def range_match(sz, rang):
+ return sz >= rang[0] and sz <= rang[1]
+
+def fd_should_filter_pkg(opts, pkg, used_map):
+ """ Do the package filtering for. """
+
+ for (attrs, attr) in [('vendors', 'vendor'),
+ ('groups', 'group'),
+ ('packagers', 'packager'),
+ ('licenses', 'license'),
+ ('arches', 'arch'),
+ ('committers', 'committer'),
+ ('buildhosts', 'buildhost'),
+ ('urls', 'url')]:
+ pats = getattr(opts, 'filter_' + attrs)
+ done = len(pats)
+ for pat in pats:
+ data = fd__get_data(pkg, attr)
+ if data == fd__unknown or fnmatch.fnmatch(data, pat):
+ used_map[attrs][pat] = True
+ done = False
+ break
+ if done:
+ return (attrs, attr)
+
+ for (attrs, attr) in [('package-sizes', 'packagesize'),
+ ('archive-sizes', 'archivesize'),
+ ('installed-sizes', 'installedsize')]:
+ rangs = getattr(opts, 'filter_' + attrs.replace('-', '_'))
+ done = len(rangs)
+ for rang in rangs:
+ data = fd__get_data(pkg, attr, strip=False)
+ if data == fd__unknown or range_match(data, rang):
+ used_map[attrs][rang] = True
+ done = False
+ break
+ if done:
+ return (attrs, attr)
+
+ return None
+
+def fd_gen_used_map(opts):
+ used_map = {}
+ for (attrs, attr) in [('vendors', 'vendor'),
+ ('groups', 'group'),
+ ('packagers', 'packager'),
+ ('licenses', 'license'),
+ ('arches', 'arch'),
+ ('committers', 'committer'),
+ ('buildhosts', 'buildhost'),
+ ('urls', 'url'),
+ ('package-sizes', 'packagesize'),
+ ('archive-sizes', 'archivesize'),
+ ('installed-sizes', 'installedsize')]:
+ used_map[attrs] = {}
+ vattrs = attrs.replace('-', '_')
+ for i in getattr(opts, 'filter_' + vattrs):
+ used_map[attrs][i] = False
+
+ return used_map
+
+def fd_chk_used_map(used_map, msg):
+ for (attrs, attr) in [('vendors', 'vendor'),
+ ('groups', 'group'),
+ ('packagers', 'packager'),
+ ('licenses', 'license'),
+ ('arches', 'arch'),
+ ('committers', 'committer'),
+ ('buildhosts', 'buildhost'),
+ ('urls', 'url')]:
+ for i in used_map[attrs]:
+ if not used_map[attrs][i]:
+ msg(attr.capitalize() +
+ ' wildcard \"%s\" did not match any packages' % i)
+
+ for (attrs, attr) in [('package-sizes', 'packagesize'),
+ ('archive-sizes', 'archivesize'),
+ ('installed-sizes', 'installedsize')]:
+ for i in used_map[attrs]:
+ if not used_map[attrs][i]:
+ if i[1] == fd__max:
+ msg(attrs[:-1].capitalize() +
+ ' range \"%d-\" did not match any packages' % i[0])
+ else:
+ msg(attrs[:-1].capitalize() +
+ ' range \"%d-%d\" did not match any packages' % i)
+
+# You might think we'd just use the exclude_hook, and call delPackage
+# and indeed that works for list updates etc.
+#
+# __but__ that doesn't work for dependancies on real updates
+#
+# So to fix deps. we need to do it at the preresolve stage and take the
+# "transaction package list" and then remove packages from that.
+#
+# __but__ that doesn't work for lists ... so we do it two ways
+#
+def fd_check_func_enter(conduit):
+ """ Stuff we need to do in both list and update modes. """
+
+ opts, args = conduit.getCmdLine()
+
+ # Quick match, so we don't do lots of work when nothing has been specified
+ ndata = True
+ for (attrs, attr) in [('vendors', 'vendor'),
+ ('groups', 'group'),
+ ('packagers', 'packager'),
+ ('licenses', 'license'),
+ ('arches', 'arch'),
+ ('committers', 'committer'),
+ ('buildhosts', 'buildhost'),
+ ('urls', 'url'),
+ ('package-sizes', 'packagesize'),
+ ('archive-sizes', 'archivesize'),
+ ('installed-sizes', 'installedsize')]:
+ vattrs = attrs.replace('-', '_')
+ if len(getattr(opts, 'filter_' + vattrs)):
+ ndata = False
+
+ ret = None
+ 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,
+ "ret_pkg_lists": ["updates"] + args[1:]}
+
+ # FIXME: delPackage() only works for updates atm.
+ valid_list_cmds = ["list", "info"]
+ for cmd in ["vendors", 'groups', 'packagers', 'licenses', 'arches',
+ 'committers', 'buildhosts', 'baseurls', 'package-sizes',
+ 'archive-sizes', 'installed-sizes', 'security', 'sec']:
+ valid_list_cmds.append("list-" + cmd)
+ valid_list_cmds.append("info-" + cmd)
+
+ if (len(args) >= 2 and args[0] in valid_list_cmds and args[1] == "updates"):
+ ret = {"skip": ndata, "list_cmd": True, "ret_pkg_lists": args[1:]}
+
+ if ret:
+ if ndata:
+ conduit.info(2, 'Skipping filters plugin, no data')
+ return (opts, ret)
+
+ if not ndata:
+ conduit.error(2, 'Skipping filters plugin, other command')
+ return (opts, {"skip": True, "list_cmd": False, "msg": True})
+
+
+_in_plugin = False
+def exclude_hook(conduit):
+ '''
+ Yum Plugin Exclude Hook:
+ Check and remove packages that don\'t align with the filters.
+ '''
+
+ global _in_plugin
+
+ opts, info = fd_check_func_enter(conduit)
+ if info["skip"]:
+ return
+
+ if not info["list_cmd"]:
+ return
+
+ if _in_plugin:
+ return
+
+ _in_plugin = True
+ conduit.info(2, 'Limiting package lists to filtered ones')
+
+ def fd_del_pkg(pkg, which):
+ """ Deletes a package from all trees that yum knows about """
+ conduit.info(3," --> %s from %s excluded (filter: %s)" %
+ (pkg, pkg.repoid, which[0]))
+ conduit.delPackage(pkg)
+
+ used_map = fd_gen_used_map(opts)
+
+ # NOTE: excludes/delPackage() doesn't work atm. for non-"list upgrades"
+ if not info['ret_pkg_lists']:
+ pkgs = conduit.getPackages()
+ else:
+ args = info['ret_pkg_lists']
+ special = ['updates']
+ pn = None
+ pkgs = []
+ if len(args) >= 1 and args[0] in special:
+ pn = args[0]
+ args = args[1:]
+ else:
+ pkgs = conduit.getPackages()
+
+ if not len(args):
+ args = None
+ if pn:
+ data = conduit._base.doPackageLists(pkgnarrow=pn, patterns=args)
+ pkgs.extend(data.updates)
+ del data
+
+ tot = 0
+ cnt = 0
+ for pkg in pkgs:
+ tot += 1
+ which = fd_should_filter_pkg(opts, pkg, used_map)
+ if which:
+ fd_del_pkg(pkg, which)
+ else:
+ cnt += 1
+ fd_chk_used_map(used_map, lambda x: conduit.error(2, x))
+ if cnt:
+ conduit.info(2, 'Left with %d of %d packages, after filters applied' % (cnt, tot))
+ else:
+ conduit.info(2, 'No packages passed the filters, %d available' % tot)
+
+ _in_plugin = False
+
+def preresolve_hook(conduit):
+ '''
+ Yum Plugin PreResolve Hook:
+ Check and remove packages that don\'t align with the filters.
+ '''
+
+ opts, info = fd_check_func_enter(conduit)
+ if info["skip"]:
+ return
+
+ if info["list_cmd"]:
+ return
+
+ conduit.info(2, 'Limiting package lists to filtered ones')
+
+ def fd_del_pkg(tspkg, which):
+ """ Deletes a package within a transaction. """
+ conduit.info(3," --> %s from %s excluded (filter: %s)" %
+ (tspkg.po, tspkg.po.repoid, which[0]))
+ tsinfo.remove(tspkg.pkgtup)
+
+ tot = 0
+ cnt = 0
+ used_map = fd_gen_used_map(opts)
+ tsinfo = conduit.getTsInfo()
+ tspkgs = tsinfo.getMembers()
+ for tspkg in tspkgs:
+ tot += 1
+ which = fd_should_filter_pkg(opts, tspkg.po, used_map)
+ if which:
+ fd_del_pkg(tspkg, which)
+ else:
+ cnt += 1
+ fd_chk_used_map(used_map, lambda x: conduit.error(2, x))
+
+ if cnt:
+ conduit.info(2, 'Left with %d of %d packages, after filters applied' % (cnt, tot))
+ else:
+ conduit.info(2, 'No packages passed the filters, %d available' % tot)
+
+def config_hook(conduit):
+ '''
+ Yum Plugin Config Hook:
+ Setup the option parser with the '--filter-*' command line options.
+ '''
+
+ parser = conduit.getOptParser()
+ if not parser:
+ return
+
+ parser.values.filter_vendors = []
+ parser.values.filter_groups = []
+ parser.values.filter_packagers = []
+ parser.values.filter_licenses = []
+ parser.values.filter_arches = []
+ parser.values.filter_committers = []
+ parser.values.filter_buildhosts = []
+ parser.values.filter_urls = []
+ parser.values.filter_packages_sizes = []
+ parser.values.filter_archive_sizes = []
+ parser.values.filter_installed_sizes = []
+ def ogroups(opt, key, val, parser):
+ parser.values.filter_groups.extend(str(val).split(","))
+ def make_nopt(attrs):
+ def func(opt, key, val, parser):
+ vals = str(val).replace(",", " ").split()
+ getattr(parser.values, 'filter_' + attrs).extend(vals)
+ return func
+ def make_szopt(attrs):
+ attrs = attrs.replace("-", "_")
+ def func(opt, key, val, parser):
+ def sz_int(x, empty_sz):
+ if x == '':
+ return empty_sz
+ mul = 1
+ conv = {'k' : 1024, 'm' : 1024 * 1024, 'g' : 1024 * 1024 * 1024}
+ if x[-1].lower() in conv:
+ mul = conv[x[-1]]
+ x = x[:-1]
+ return int(x) * mul
+ vals = str(val).replace(",", " ").split()
+ for val in vals:
+ rang = val.split("-")
+ if len(rang) > 2:
+ msg = "%s was passed an invalid range: %s" % (attrs, val)
+ raise OptionValueError, msg
+ if len(rang) < 2:
+ rang = (rang[0], rang[0])
+ else:
+ rang = (sz_int(rang[0], 0), sz_int(rang[1], fd__max))
+
+ getattr(parser.values, 'filter_' + attrs).append(rang)
+ return func
+
+ for (attrs, attr) in [('vendors', 'vendor'),
+ ('groups', 'group'),
+ ('packagers', 'packager'),
+ ('licenses', 'license'),
+ ('arches', 'arch'),
+ ('committers', 'committer'),
+ ('buildhosts', 'buildhost'),
+ ('urls', 'url')]:
+ parser.add_option('--filter-' + attrs, action="callback",
+ callback=make_nopt(attrs), default=[], type="string",
+ help='Filter to packages with a matching ' + attr)
+
+ for (attrs, attr) in [('package-sizes', 'packagesize'),
+ ('archive-sizes', 'archivesize'),
+ ('installed-sizes', 'installedsize')]:
+ parser.add_option('--filter-' + attrs, action="callback",
+ callback=make_szopt(attrs), default=[], type="string",
+ help='Filter to packages with a %s in the given range'
+ % attr)
+
+if __name__ == '__main__':
+ print "This is a plugin that is supposed to run from inside YUM"
diff --git a/yum-utils.spec b/yum-utils.spec
index db79ce3..3bf8bdc 100644
--- a/yum-utils.spec
+++ b/yum-utils.spec
@@ -209,8 +209,20 @@ Group: System Environment/Base
Requires: yum >= 3.0.5
%description -n yum-list-data
-This plugin adds the commands list-vendors, groups, baseurls, packagers,
-buildhosts, licenses and arches.
+This plugin adds the commands list- vendors, groups, packagers, licenses,
+arches, committers, buildhosts, baseurls, package-sizes, archive-sizes and
+installed-sizes.
+
+%package -n yum-filter-data
+Summary: Yum plugin to list filter based on package data
+Group: System Environment/Base
+Requires: yum >= 3.0.5
+
+%description -n yum-filter-data
+This plugin adds the options --filter- vendors, groups, packagers, licenses,
+arches, committers, buildhosts, baseurls, package-sizes, archive-sizes and
+installed-sizes. Note that each package must match at least one pattern/range in
+each category, if any were specified.
%package -n yum-tmprepo
Summary: Yum plugin to add temporary repositories
@@ -234,7 +246,7 @@ make -C updateonboot DESTDIR=$RPM_BUILD_ROOT install
# Plugins to install
plugins="changelog fastestmirror fedorakmod protectbase versionlock tsflags kernel-module \
downloadonly allowdowngrade skip-broken priorities refresh-updatesd merge-conf \
- security protect-packages basearchonly upgrade-helper aliases list-data tmprepo"
+ security protect-packages basearchonly upgrade-helper aliases list-data filter-data tmprepo"
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/ $RPM_BUILD_ROOT/usr/lib/yum-plugins/
@@ -390,6 +402,11 @@ fi
%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/list-data.conf
/usr/lib/yum-plugins/list-data.*
+%files -n yum-filter-data
+%defattr(-, root, root)
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/filter-data.conf
+/usr/lib/yum-plugins/filter-data.*
+
%files -n yum-tmprepo
%defattr(-, root, root)
%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/tmprepo.conf
@@ -397,8 +414,12 @@ fi
%changelog
+* Fri Fed 1 2008 James Antill <james at fedoraproject.org>
+- Add filter-data plugin
+
* Wed Jan 30 2008 Tim Lauridsen <timlau at fedoraproject.org>
- mark as 1.1.11
+
* Sun Jan 13 2008 Seth Vidal <skvidal at fedoraproject.org>
- add repodiff
More information about the Yum-cvs-commits
mailing list