Package bodhi :: Module modifyrepo
[hide private]
[frames] | no frames]

Source Code for Module bodhi.modifyrepo

  1  #!/usr/bin/env python 
  2  # $Id: modifyrepo.py,v 1.1 2006/12/07 07:19:41 lmacken Exp $ 
  3  # 
  4  # This tools is used to insert arbitrary metadata into an RPM repository. 
  5  # Example: 
  6  #           ./modifyrepo.py updateinfo.xml myrepo/repodata 
  7  # or in Python: 
  8  #           >>> from modifyrepo import RepoMetadata 
  9  #           >>> repomd = RepoMetadata('myrepo/repodata') 
 10  #           >>> repomd.add('updateinfo.xml') 
 11  # 
 12  # This program is free software; you can redistribute it and/or modify 
 13  # it under the terms of the GNU General Public License as published by 
 14  # the Free Software Foundation; either version 2 of the License, or 
 15  # (at your option) any later version. 
 16  # 
 17  # This program is distributed in the hope that it will be useful, 
 18  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 19  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 20  # GNU General Public License for more details. 
 21  # 
 22  # Luke Macken <lmacken@redhat.com> 
 23   
 24  """ 
 25      This tool is in CVS HEAD of createrepo  
 26  """ 
 27   
 28  import os 
 29  import sys 
 30  import sha 
 31  import gzip 
 32   
 33  from xml.dom import minidom 
 34  from bodhi.exceptions import RepositoryNotFound 
 35   
36 -class RepoMetadata:
37
38 - def __init__(self, repo):
39 """ Parses the repomd.xml file existing in the given repo directory. """ 40 self.repodir = os.path.abspath(repo) 41 self.repomdxml = os.path.join(self.repodir, 'repomd.xml') 42 if not os.path.exists(self.repomdxml): 43 raise RepositoryNotFound, self.repomdxml 44 self.doc = minidom.parse(self.repomdxml)
45
46 - def _insert_element(self, parent, name, attrs={}, text=None):
47 child = self.doc.createElement(name) 48 for item in attrs.items(): 49 child.setAttribute(item[0], item[1]) 50 if text: 51 txtnode = self.doc.createTextNode(text) 52 child.appendChild(txtnode) 53 parent.appendChild(child) 54 return child
55
56 - def add(self, metadata):
57 """ Insert arbitrary metadata into this repository. 58 metadata can be either an xml.dom.minidom.Document object, or 59 a filename. 60 """ 61 md = None 62 if not metadata: 63 raise Exception('metadata cannot be None') 64 if isinstance(metadata, minidom.Document): 65 md = metadata.toxml() 66 mdname = 'updateinfo.xml' 67 elif isinstance(metadata, str): 68 if os.path.exists(metadata): 69 oldmd = file(metadata, 'r') 70 md = oldmd.read() 71 oldmd.close() 72 mdname = os.path.basename(metadata) 73 else: 74 raise Exception('%s not found' % metadata) 75 else: 76 raise Exception('invalid metadata type') 77 78 ## Compress the metadata and move it into the repodata 79 mdname += '.gz' 80 mdtype = mdname.split('.')[0] 81 destmd = os.path.join(self.repodir, mdname) 82 newmd = gzip.GzipFile(destmd, 'wb') 83 newmd.write(md) 84 newmd.close() 85 print "Wrote:", destmd 86 87 ## Read the gzipped metadata 88 f = file(destmd, 'r') 89 newmd = f.read() 90 f.close() 91 92 ## Remove any stale metadata 93 for elem in self.doc.getElementsByTagName('data'): 94 if elem.attributes['type'].value == mdtype: 95 self.doc.firstChild.removeChild(elem) 96 ## Build the metadata 97 root = self.doc.firstChild 98 data = self._insert_element(root, 'data', attrs={ 'type' : mdtype }) 99 self._insert_element(data, 'location', 100 attrs={ 'href' : 'repodata/' + mdname }) 101 self._insert_element(data, 'checksum', attrs={ 'type' : 'sha' }, 102 text=sha.new(newmd).hexdigest()) 103 self._insert_element(data, 'timestamp', 104 text=str(os.stat(destmd).st_mtime)) 105 self._insert_element(data, 'open-checksum', attrs={ 'type' : 'sha' }, 106 text=sha.new(md).hexdigest()) 107 108 #print " type =", mdtype 109 #print " location =", 'repodata/' + mdname 110 #print " checksum =", sha.new(newmd).hexdigest() 111 #print " timestamp =", str(os.stat(destmd).st_mtime) 112 #print " open-checksum =", sha.new(md).hexdigest() 113 114 ## Write the updated repomd.xml 115 outmd = file(self.repomdxml, 'w') 116 self.doc.writexml(outmd) 117 outmd.close() 118 print "Wrote:", self.repomdxml
119 120 121 if __name__ == '__main__': 122 if len(sys.argv) != 3 or '-h' in sys.argv: 123 print "Usage: %s <input metadata> <output repodata>" % sys.argv[0] 124 sys.exit() 125 126 repomd = RepoMetadata(sys.argv[2]) 127 repomd.add(sys.argv[1]) 128