modifyrepo.py
[email protected] Fri, 29 Jul 2011 17:46:52 +0000 (UTC)
| Newsgroups | gmane.linux.rpm.metadata |
|---|---|
| Message-ID | <[email protected]> |
modifyrepo.py | 97 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 22 deletions(-) New commits: commit c18b233767af8c9bea91bc85a759affbf29c2447 Author: Daniel Mach <[email protected]> Date: Fri Jul 29 13:46:14 2011 -0400 apply modifyrepo --remove patch from Dmach closes rhbug# 713747 diff --git a/modifyrepo.py b/modifyrepo.py index 17094a4..c3370e8 100755 --- a/modifyrepo.py +++ b/modifyrepo.py @@ -1,11 +1,15 @@ #!/usr/bin/python -# This tools is used to insert arbitrary metadata into an RPM repository. +# This tool is used to manipulate arbitrary metadata in a RPM repository. # Example: # ./modifyrepo.py updateinfo.xml myrepo/repodata +# or +# ./modifyrepo.py --remove updateinfo.xml myrepo/repodata # or in Python: # >>> from modifyrepo import RepoMetadata # >>> repomd = RepoMetadata('myrepo/repodata') # >>> repomd.add('updateinfo.xml') +# or +# >>> repomd.remove('updateinfo.xml') # # 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 @@ -20,6 +24,7 @@ # (C) Copyright 2006 Red Hat, Inc. # Luke Macken <[email protected]> # modified by Seth Vidal 2008 +# modified by Daniel Mach 2011 import os import sys @@ -49,6 +54,35 @@ class RepoMetadata: except RepoMDError, e: raise MDError, 'Could not parse %s' % self.repomdxml + def _get_mdtype(self, mdname, mdtype=None): + """ Get mdtype from existing mdtype or from a mdname. """ + if mdtype: + return mdtype + return mdname.split('.')[0] + + def _print_repodata(self, repodata): + """ Print repodata details. """ + print " type =", repodata.type + print " location =", repodata.location[1] + print " checksum =", repodata.checksum[1] + print " timestamp =", repodata.timestamp + print " open-checksum =", repodata.openchecksum[1] + + def _write_repomd(self): + """ Write the updated repomd.xml. """ + outmd = file(self.repomdxml, 'w') + outmd.write(self.repoobj.dump_xml()) + outmd.close() + print "Wrote:", self.repomdxml + + def _remove_repodata_file(self, repodata): + """ Remove a file specified in repodata location """ + try: + os.remove(repodata.location[1]) + except OSError, ex: + if ex.errno != 2: + # continue on a missing file + raise MDError("could not remove file %s" % repodata.location[1]) def add(self, metadata, mdtype=None): """ Insert arbitrary metadata into this repository. @@ -78,9 +112,8 @@ class RepoMetadata: ## Compress the metadata and move it into the repodata if not mdname.endswith('.gz'): mdname += '.gz' - if not mdtype: - mdtype = mdname.split('.')[0] - + mdtype = self._get_mdtype(mdname, mdtype) + destmd = os.path.join(self.repodir, mdname) newmd = GzipFile(filename=destmd, mode='wb') newmd.write(md) @@ -91,11 +124,8 @@ class RepoMetadata: csum, destmd = checksum_and_rename(destmd, self.checksum_type) base_destmd = os.path.basename(destmd) - - ## Remove any stale metadata - if mdtype in self.repoobj.repoData: - del self.repoobj.repoData[mdtype] - + # Remove any stale metadata + old_rd = self.repoobj.repoData.pop(mdtype, None) new_rd = RepoData() new_rd.type = mdtype @@ -105,18 +135,28 @@ class RepoMetadata: new_rd.size = str(os.stat(destmd).st_size) new_rd.timestamp = str(os.stat(destmd).st_mtime) self.repoobj.repoData[new_rd.type] = new_rd - - print " type =", new_rd.type - print " location =", new_rd.location[1] - print " checksum =", new_rd.checksum[1] - print " timestamp =", new_rd.timestamp - print " open-checksum =", new_rd.openchecksum[1] - - ## Write the updated repomd.xml - outmd = file(self.repomdxml, 'w') - outmd.write(self.repoobj.dump_xml()) - outmd.close() - print "Wrote:", self.repomdxml + self._print_repodata(new_rd) + self._write_repomd() + + if old_rd is not None and old_rd.location[1] != new_rd.location[1]: + # remove the old file when overwriting metadata + # with the same mdtype but different location + self._remove_repodata_file(old_rd) + + def remove(self, metadata, mdtype=None): + """ Remove metadata from this repository. """ + mdname = metadata + mdtype = self._get_mdtype(mdname, mdtype) + + old_rd = self.repoobj.repoData.pop(mdtype, None) + if old_rd is None: + print "Metadata not found: %s" % mdtype + return + + self._remove_repodata_file(old_rd) + print "Removed:" + self._print_repodata(old_rd) + self._write_repomd() def main(args): @@ -124,7 +164,9 @@ def main(args): # query options parser.add_option("--mdtype", dest='mdtype', help="specific datatype of the metadata, will be derived from the filename if not specified") - parser.usage = "modifyrepo [options] <input_metadata> <output repodata>" + parser.add_option("--remove", action="store_true", + help="remove specified file from repodata") + parser.usage = "modifyrepo [options] [--remove] <input_metadata> <output repodata>" (opts, argsleft) = parser.parse_args(args) if len(argsleft) != 2: @@ -137,6 +179,17 @@ def main(args): except MDError, e: print "Could not access repository: %s" % str(e) return 1 + + # remove + if opts.remove: + try: + repomd.remove(metadata) + except MDError, ex: + print "Could not remove metadata: %s" % (metadata, str(ex)) + return 1 + return + + # add try: repomd.add(metadata, mdtype=opts.mdtype) except MDError, e: