[Rpm-metadata] modifyrepo.py

skvidal at osuosl.org skvidal at osuosl.org
Fri Jul 29 17:46:52 UTC 2011


 modifyrepo.py |   97 ++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 75 insertions(+), 22 deletions(-)

New commits:
commit c18b233767af8c9bea91bc85a759affbf29c2447
Author: Daniel Mach <dmach at redhat.com>
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 <lmacken at redhat.com>
 # 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:


More information about the Rpm-metadata mailing list