[yum-git] 9 commits - docs/repoquery.1 plugins/keys plugins/list-data repoquery.py yum-utils.spec
James Antill
james at linux.duke.edu
Fri Apr 18 19:15:55 UTC 2008
docs/repoquery.1 | 5
plugins/keys/keys.conf | 2
plugins/keys/keys.py | 234 +++++++++++++++++++++++++++++++++++++++++
plugins/list-data/list-data.py | 16 ++
repoquery.py | 62 ++++++++--
yum-utils.spec | 19 +++
6 files changed, 316 insertions(+), 22 deletions(-)
New commits:
commit 05764f09a1868461f74ae5fff1b6feec33e0a6ec
Author: James Antill <james at and.org>
Date: Fri Apr 18 15:15:33 2008 -0400
Add k,m,g,t and h ... and documentation about the special size syntax
diff --git a/docs/repoquery.1 b/docs/repoquery.1
index 8e2048a..104f7e5 100644
--- a/docs/repoquery.1
+++ b/docs/repoquery.1
@@ -74,8 +74,10 @@ Use name-epoch:version-release.architecture output format (default)
Use epoch:name-version-release.architecture output format
(easier to parse than nevra)
.IP "\fB\--qf=FORMAT, \-\-queryformat=FORMAT\fP"
-Specify custom output format for queries. Note that you can add ":date", ":day"
-and ":isodate" to all the tags that are a time.
+Specify custom output format for queries. You can add ":date", ":day" and
+":isodate" to all the tags that are a time, and you can add ":k", ":m", ":g",
+":t" and ":h" to sizes. You can also specify field width as in
+sprintf (Eg. %-20{name})
.PP
.SH "PACKAGE SELECTION OPTIONS"
diff --git a/repoquery.py b/repoquery.py
index 5868655..d21f423 100755
--- a/repoquery.py
+++ b/repoquery.py
@@ -80,9 +80,40 @@ def sec2date(timestr):
def sec2day(timestr):
return time.strftime("%a %b %d %Y", time.gmtime(int(timestr)))
+def _size2val(size, off, ui):
+ size = float(size)
+ off = 1024
+ if False: pass
+ elif size >= (off * 100):
+ return "%f%s" % ((size / off), ui)
+ elif size >= (off * 10):
+ return "%.1f%s" % ((size / off), ui)
+ return "%.2f%s" % ((size / off), ui)
+def size2k(size):
+ return _size2val(size, 1024, " K")
+def size2m(size):
+ return _size2val(size, 1024 * 1024, " M")
+def size2g(size):
+ return _size2val(size, 1024 * 1024 * 1024, " G")
+def size2t(size):
+ return _size2val(size, 1024 * 1024 * 1024 * 1024, " T")
+def size2h(size):
+ size = int(size)
+ if size >= (1024 * 1024 * 1024 * 1024): # Really hope not
+ return size2t(size)
+ if size >= ( 1024 * 1024 * 1024):
+ return size2g(size)
+ if size >= ( 1024 * 1024):
+ return size2m(size)
+ return size2k(size)
+
convertmap = { 'date': sec2date,
'day': sec2day,
'isodate': sec2isodate,
+ 'k': size2k,
+ 'm': size2m,
+ 'g': size2g,
+ 'h': size2h,
}
class queryError(exceptions.Exception):
commit 92785e60a30b80e0f7554d3ff0f4623056cd7eb1
Author: James Antill <james at and.org>
Date: Fri Apr 18 14:01:59 2008 -0400
Remove unused function, add nevra format
diff --git a/repoquery.py b/repoquery.py
index 665dc5b..5868655 100755
--- a/repoquery.py
+++ b/repoquery.py
@@ -85,22 +85,6 @@ convertmap = { 'date': sec2date,
'isodate': sec2isodate,
}
-def rpmevr(e, v, r):
- """
- Given epoch, version and release strings, return one string
- representing the combination, possibly omitting any of the three.
- """
- et = ""
- vt = ""
- rt = ""
- if e and e != "0":
- et = "%s:" % e
- if v:
- vt = "%s" % v
- if r:
- rt = "-%s" % r
- return "%s%s%s" % (et, vt, rt)
-
class queryError(exceptions.Exception):
def __init__(self, msg):
exceptions.Exception.__init__(self)
@@ -208,6 +192,17 @@ class pkgQuery:
def fmt_list(self, **kw):
return "\n".join(self.files())
+ def fmt_evr(self, **kw):
+ return "%(epoch)s:%(version)s-%(release)s" % self
+ def fmt_nevr(self, **kw):
+ return "%(name)s-%(evr)s" % self
+ def fmt_envr(self, **kw):
+ return "%(epoch)s:%(name)s-%(version)s-%(release)s" % self
+ def fmt_nevra(self, **kw):
+ return "%(nevr)s.%(arch)s" % self
+ def fmt_envra(self, **kw):
+ return "%(envr)s.%(arch)s" % self
+
class repoPkgQuery(pkgQuery):
"""
I wrap a query of a non-installed package available in the repository.
commit 80963881d45d821fdcc7b6f5d4c6357851b5e831
Author: James Antill <james at and.org>
Date: Fri Apr 18 13:46:51 2008 -0400
Add isodate and documentation about the special time syntax
diff --git a/docs/repoquery.1 b/docs/repoquery.1
index bdae835..8e2048a 100644
--- a/docs/repoquery.1
+++ b/docs/repoquery.1
@@ -74,7 +74,8 @@ Use name-epoch:version-release.architecture output format (default)
Use epoch:name-version-release.architecture output format
(easier to parse than nevra)
.IP "\fB\--qf=FORMAT, \-\-queryformat=FORMAT\fP"
-Specify custom output format for queries.
+Specify custom output format for queries. Note that you can add ":date", ":day"
+and ":isodate" to all the tags that are a time.
.PP
.SH "PACKAGE SELECTION OPTIONS"
diff --git a/repoquery.py b/repoquery.py
index 60b88ab..665dc5b 100755
--- a/repoquery.py
+++ b/repoquery.py
@@ -71,6 +71,9 @@ querytags = [ 'name', 'version', 'release', 'epoch', 'arch', 'summary',
'relativepath', 'hdrstart', 'hdrend', 'id',
]
+def sec2isodate(timestr):
+ return time.strftime("%F %T", time.gmtime(int(timestr)))
+
def sec2date(timestr):
return time.ctime(int(timestr))
@@ -79,6 +82,7 @@ def sec2day(timestr):
convertmap = { 'date': sec2date,
'day': sec2day,
+ 'isodate': sec2isodate,
}
def rpmevr(e, v, r):
commit 49977709378a2c1626360e73b0cc5b7c70008448
Author: James Antill <james at and.org>
Date: Sat Apr 12 11:18:54 2008 -0400
Fix keys compare/sort
diff --git a/plugins/keys/keys.py b/plugins/keys/keys.py
index 5a1ddcc..d84b985 100644
--- a/plugins/keys/keys.py
+++ b/plugins/keys/keys.py
@@ -66,14 +66,14 @@ class Key:
if other is None:
return 1
- ret = cmp(self.sum_type, self.sum_type)
+ ret = cmp(self.sum_type, other.sum_type)
if ret: return ret
- ret = cmp(self.sum_auth, self.sum_auth)
+ ret = cmp(self.sum_auth, other.sum_auth)
if ret: return ret
- ret = cmp(self.keyid, self.keyid)
+ ret = cmp(self.keyid, other.keyid)
if ret: return ret
# Never gets here on diff. keys?
- ret = cmp(self.createts, self.createts)
+ ret = cmp(self.createts, other.createts)
return ret
class KeysListCommand:
commit aa6c3fac3fa868b5fef69b7c40b880846a99fc31
Author: James Antill <james at and.org>
Date: Sat Apr 12 01:34:34 2008 -0400
Fix None values, don't try and convert unicode to str()
diff --git a/plugins/list-data/list-data.py b/plugins/list-data/list-data.py
index 9ca303c..5744ff5 100755
--- a/plugins/list-data/list-data.py
+++ b/plugins/list-data/list-data.py
@@ -42,6 +42,14 @@ def loc_num(x):
""" Return a string of a number in the readable "locale" format. """
return locale.format("%d", int(x), True)
+def to_str(obj):
+ """ Convert something to a string, if it isn't one. """
+ # NOTE: unicode counts as a string just fine. We just want objects to call
+ # their __str__ methods.
+ if not isinstance(obj, basestring):
+ obj = str(obj)
+ return obj
+
requires_api_version = '2.5'
plugin_type = (TYPE_INTERACTIVE,)
@@ -100,7 +108,7 @@ Display aggregate data on the %s attribute of a group of packages""" % self.attr
fmt = "%%-%ds %%6s (%%3d%%%%)" % maxlen
for data in sorted(calc):
val = len(calc[data])
- msg(fmt % (str(data), loc_num(val), (100 * val) / totlen))
+ msg(fmt % (to_str(data), loc_num(val), (100 * val) / totlen))
self.show_pkgs(msg, data, calc[data])
# pkg.vendor has weird values, for instance
@@ -110,11 +118,11 @@ Display aggregate data on the %s attribute of a group of packages""" % self.attr
val = getattr(data, self.attr)
if val is None:
- return self.unknown
+ return (self.unknown, self.unknown)
if type(val) == type([]):
return (self.unknown, self.unknown)
- tval = str(val).strip()
+ tval = to_str(val).strip()
if tval == "":
return (self.unknown, self.unknown)
@@ -166,7 +174,7 @@ class InfoDataCommands(ListDataCommands):
if type(val) == type([]):
val = ", ".join(sorted(val))
- linelen = len(val) + len(str(pkg))
+ linelen = len(val) + len(to_str(pkg))
if linelen < 77:
msg(" %s %*s%s" % (pkg, 77 - linelen, '', val))
else:
commit 0efc9e6c41ece1c24f1f68a2fd2ba85b5807deaf
Author: James Antill <james at and.org>
Date: Sat Apr 12 01:33:50 2008 -0400
Only root can run keys-remove
diff --git a/plugins/keys/keys.py b/plugins/keys/keys.py
index e5ee203..5a1ddcc 100644
--- a/plugins/keys/keys.py
+++ b/plugins/keys/keys.py
@@ -220,6 +220,12 @@ class KeysRemoveCommand(KeysListCommand):
def match_key(self, patterns, key):
return match_keys(patterns, key, globs=False)
+ def doCheck(self, base, basecmd, extcmds):
+ if base.conf.uid:
+ raise PluginYumExit('You need to be root to perform this command.')
+ if not len(extcmds):
+ raise PluginYumExit('You need to specify a key to remove.')
+
def config_hook(conduit):
conduit.registerCommand(KeysListCommand())
commit 655a864d7217d0f46b977e57478b91e44ac16b8f
Author: James Antill <james at and.org>
Date: Thu Apr 10 10:51:42 2008 -0400
Add install code for keys
diff --git a/yum-utils.spec b/yum-utils.spec
index 8b730bb..2ad7425 100644
--- a/yum-utils.spec
+++ b/yum-utils.spec
@@ -248,6 +248,15 @@ This plugin adds the commands verify, verify-all and verify-rpm. There are
also a couple of options. This command works like rpm -V, to verify your
installation.
+%package -n yum-keys
+Summary: Yum plugin to deal with signing keys
+Group: System Environment/Base
+Requires: yum >= 3.2.8
+
+%description -n yum-keys
+This plugin adds the commands keys, keys-info, keys-data and keys-remove. They
+allow you to query and remove signing keys.
+
%prep
%setup -q
@@ -259,7 +268,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 filter-data tmprepo verify"
+ security protect-packages basearchonly upgrade-helper aliases list-data filter-data tmprepo verify keys"
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/ $RPM_BUILD_ROOT/usr/lib/yum-plugins/
@@ -436,7 +445,15 @@ fi
/usr/lib/yum-plugins/verify.*
%{_mandir}/man1/yum-verify.1.*
+%files -n yum-keys
+%defattr(-, root, root)
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/keys.conf
+/usr/lib/yum-plugins/keys.*
+
%changelog
+* Fri Apr 10 2008 James Antill <james at fedoraproject.org>
+- Add keys plugin
+
* Fri Mar 31 2008 James Antill <james at fedoraproject.org>
- Add yum-aliases man page
commit c7a57202c929a29abce753a5dad48345c4632bc6
Author: James Antill <james at and.org>
Date: Thu Apr 10 10:43:07 2008 -0400
Tweak keys* commands, add keys-remove command
diff --git a/plugins/keys/keys.py b/plugins/keys/keys.py
index dbb15d6..e5ee203 100644
--- a/plugins/keys/keys.py
+++ b/plugins/keys/keys.py
@@ -26,13 +26,19 @@ import yum.pgpmsg
requires_api_version = '2.1'
plugin_type = (TYPE_INTERACTIVE,)
-def match_one_of(patterns, key):
+def match_keys(patterns, key, globs=True):
for pat in patterns:
if pat == key.keyid:
return True
if pat == "%s-%x" % (key.keyid, key.createts):
return True
- if fnmatch.fnmatch(key.sum_auth, pat):
+ if pat == key.sum_auth:
+ return True
+ if pat == key.sum_auth_name:
+ return True
+ if pat == key.sum_auth_email:
+ return True
+ if globs and fnmatch.fnmatch(key.sum_auth, pat):
return True
return False
@@ -45,6 +51,17 @@ class Key:
self.sum_auth = sum_auth
self.data = data
+ email_beg = sum_auth.rfind('<')
+ if email_beg == -1:
+ self.sum_auth_name = sum_auth
+ self.sum_auth_email = ""
+ else:
+ self.sum_auth_name = sum_auth[:email_beg]
+ if sum_auth[-1] == '>':
+ self.sum_auth_email = sum_auth[email_beg+1:-1]
+ else:
+ self.sum_auth_email = sum_auth[email_beg:]
+
def __cmp__(self, other):
if other is None:
return 1
@@ -74,12 +91,18 @@ class KeysListCommand:
pass
def show_hdr(self):
- print "%-4.4s %-66.66s %s" % ("Type", "Key owner", "Key ID")
+ print "%-40.40s %-21.21s %s" % ("Key owner", "Key email", "Key ID")
+
+ def match_key(self, patterns, key):
+ return match_keys(patterns, key)
- def show_key(self, key):
- print "%-4.4s %-66.66s %s" % (key.sum_type, key.sum_auth, key.keyid)
+ def show_key(self, base, key):
+ print "%-40.40s %-21.21s %s-%x" % (key.sum_auth_name,key.sum_auth_email,
+ key.keyid, key.createts)
def doCommand(self, base, basecmd, extcmds):
+ self.exit_code = 0
+
keys = []
ts = rpmUtils.transaction.TransactionWrapper(base.conf.installroot)
for hdr in ts.dbMatch('name', 'gpg-pubkey'):
@@ -100,13 +123,13 @@ class KeysListCommand:
done = False
for key in sorted(keys):
- if not len(extcmds) or match_one_of(extcmds, key):
+ if not len(extcmds) or self.match_key(extcmds, key):
if not done:
self.show_hdr()
done = True
- self.show_key(key)
+ self.show_key(base, key)
- return 0, [basecmd + ' done']
+ return self.exit_code, [basecmd + ' done']
def needTs(self, base, basecmd, extcmds):
return False
@@ -122,27 +145,31 @@ class KeysInfoCommand(KeysListCommand):
def show_hdr(self):
pass
- def show_key(self, key):
+ def show_key(self, base, key):
+ pkg = "gpg-pubkey-%s-%x" % (key.keyid, key.createts)
if key.sum_type == '<?>':
print """\
-Type : %s
+Type : Unknown
+Rpm PKG : %s
Key owner : %s
-Rpm Key ID: %s
+Key email : %s
Created : %s
-""" % (key.sum_type, key.sum_auth, key.keyid, time.ctime(key.createts))
+""" % (pkg, key.sum_auth_name, key.sum_auth_email, time.ctime(key.createts))
else:
gpg_cert = yum.pgpmsg.decode_msg(key.data)
print """\
Type : %s
+Rpm PKG : %s
Key owner : %s
-Rpm Key ID : %s
+Key email : %s
Created : %s
Version : PGP Public Key Certificate v%d
Primary ID : %s
Algorithm : %s
Fingerprint: %s
Key ID : %s
-""" % (key.sum_type, key.sum_auth, key.keyid, time.ctime(key.createts),
+""" % (key.sum_type, pkg, key.sum_auth_name, key.sum_auth_email,
+ time.ctime(key.createts),
gpg_cert.version, gpg_cert.user_id,
yum.pgpmsg.algo_pk_to_str[gpg_cert.public_key.pk_algo],
yum.pgpmsg.str_to_hex(gpg_cert.public_key.fingerprint()),
@@ -160,19 +187,42 @@ class KeysDataCommand(KeysListCommand):
def show_hdr(self):
pass
- def show_key(self, key):
+ def show_key(self, base, key):
print """\
Type : %s
Key owner: %s
+Key email: %s
Key ID : %s
Created : %s
Raw Data :
%s
-""" % (key.sum_type, key.sum_auth, key.keyid, time.ctime(key.createts),
+""" % (key.sum_type, key.sum_auth_name, key.sum_auth_email,
+ key.keyid, time.ctime(key.createts),
key.data.replace('\n', '\n '))
+class KeysRemoveCommand(KeysListCommand):
+
+ def getNames(self):
+ return ["keys-remove", "keys-erase"]
+
+ def getSummary(self):
+ return "Remove a public key block for signing data"
+
+ def show_hdr(self):
+ pass
+
+ def show_key(self, base, key):
+ release = "%x" % key.createts
+ base.remove(name='gpg-pubkey', version=key.keyid, release=release)
+ self.exit_code = 2
+
+ def match_key(self, patterns, key):
+ return match_keys(patterns, key, globs=False)
+
+
def config_hook(conduit):
conduit.registerCommand(KeysListCommand())
conduit.registerCommand(KeysInfoCommand())
conduit.registerCommand(KeysDataCommand())
+ conduit.registerCommand(KeysRemoveCommand())
commit b878f85c1e7cba0d9e6fad64a0ff5ef47b15afa9
Author: James Antill <james at and.org>
Date: Thu Apr 10 02:41:07 2008 -0400
Plugin for yum commands to query info. on installed signing keys
diff --git a/plugins/keys/keys.conf b/plugins/keys/keys.conf
new file mode 100644
index 0000000..8e4d76c
--- /dev/null
+++ b/plugins/keys/keys.conf
@@ -0,0 +1,2 @@
+[main]
+enabled=1
diff --git a/plugins/keys/keys.py b/plugins/keys/keys.py
new file mode 100644
index 0000000..dbb15d6
--- /dev/null
+++ b/plugins/keys/keys.py
@@ -0,0 +1,178 @@
+#!/usr/bin/python
+
+# 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.
+#
+# by James Antill
+
+from yum.plugins import TYPE_INTERACTIVE
+import rpmUtils.transaction
+
+import time
+import fnmatch
+import yum.pgpmsg
+
+requires_api_version = '2.1'
+plugin_type = (TYPE_INTERACTIVE,)
+
+def match_one_of(patterns, key):
+ for pat in patterns:
+ if pat == key.keyid:
+ return True
+ if pat == "%s-%x" % (key.keyid, key.createts):
+ return True
+ if fnmatch.fnmatch(key.sum_auth, pat):
+ return True
+ return False
+
+class Key:
+
+ def __init__(self, keyid, createts, sum_type, sum_auth, data):
+ self.keyid = keyid
+ self.createts = createts
+ self.sum_type = sum_type
+ self.sum_auth = sum_auth
+ self.data = data
+
+ def __cmp__(self, other):
+ if other is None:
+ return 1
+
+ ret = cmp(self.sum_type, self.sum_type)
+ if ret: return ret
+ ret = cmp(self.sum_auth, self.sum_auth)
+ if ret: return ret
+ ret = cmp(self.keyid, self.keyid)
+ if ret: return ret
+ # Never gets here on diff. keys?
+ ret = cmp(self.createts, self.createts)
+ return ret
+
+class KeysListCommand:
+
+ def getNames(self):
+ return ["keys", "keys-list"]
+
+ def getUsage(self):
+ return "[key-wildcard]"
+
+ def getSummary(self):
+ return "Lists keys for signing data"
+
+ def doCheck(self, base, basecmd, extcmds):
+ pass
+
+ def show_hdr(self):
+ print "%-4.4s %-66.66s %s" % ("Type", "Key owner", "Key ID")
+
+ def show_key(self, key):
+ print "%-4.4s %-66.66s %s" % (key.sum_type, key.sum_auth, key.keyid)
+
+ def doCommand(self, base, basecmd, extcmds):
+ keys = []
+ ts = rpmUtils.transaction.TransactionWrapper(base.conf.installroot)
+ for hdr in ts.dbMatch('name', 'gpg-pubkey'):
+ keyid = hdr['version']
+ createts = int(hdr['release'], 16)
+
+ sum_auth = hdr['summary']
+ sum_auth = sum_auth.strip()
+ if not sum_auth.startswith('gpg(') or not sum_auth.endswith(')'):
+ sum_type = "<?>"
+ else:
+ sum_auth = sum_auth[4:-1]
+ sum_type = "GPG"
+
+ data = hdr['description']
+
+ keys.append(Key(keyid, createts, sum_type, sum_auth, data))
+
+ done = False
+ for key in sorted(keys):
+ if not len(extcmds) or match_one_of(extcmds, key):
+ if not done:
+ self.show_hdr()
+ done = True
+ self.show_key(key)
+
+ return 0, [basecmd + ' done']
+
+ def needTs(self, base, basecmd, extcmds):
+ return False
+
+class KeysInfoCommand(KeysListCommand):
+
+ def getNames(self):
+ return ["keys-info"]
+
+ def getSummary(self):
+ return "Full information keys for signing data"
+
+ def show_hdr(self):
+ pass
+
+ def show_key(self, key):
+ if key.sum_type == '<?>':
+ print """\
+Type : %s
+Key owner : %s
+Rpm Key ID: %s
+Created : %s
+""" % (key.sum_type, key.sum_auth, key.keyid, time.ctime(key.createts))
+ else:
+ gpg_cert = yum.pgpmsg.decode_msg(key.data)
+ print """\
+Type : %s
+Key owner : %s
+Rpm Key ID : %s
+Created : %s
+Version : PGP Public Key Certificate v%d
+Primary ID : %s
+Algorithm : %s
+Fingerprint: %s
+Key ID : %s
+""" % (key.sum_type, key.sum_auth, key.keyid, time.ctime(key.createts),
+ gpg_cert.version, gpg_cert.user_id,
+ yum.pgpmsg.algo_pk_to_str[gpg_cert.public_key.pk_algo],
+ yum.pgpmsg.str_to_hex(gpg_cert.public_key.fingerprint()),
+ yum.pgpmsg.str_to_hex(gpg_cert.public_key.key_id()))
+
+
+class KeysDataCommand(KeysListCommand):
+
+ def getNames(self):
+ return ["keys-data"]
+
+ def getSummary(self):
+ return "Show public key block information for signing data"
+
+ def show_hdr(self):
+ pass
+
+ def show_key(self, key):
+ print """\
+Type : %s
+Key owner: %s
+Key ID : %s
+Created : %s
+Raw Data :
+ %s
+""" % (key.sum_type, key.sum_auth, key.keyid, time.ctime(key.createts),
+ key.data.replace('\n', '\n '))
+
+
+def config_hook(conduit):
+ conduit.registerCommand(KeysListCommand())
+ conduit.registerCommand(KeysInfoCommand())
+ conduit.registerCommand(KeysDataCommand())
More information about the Yum-cvs-commits
mailing list