diff --git a/bodhi/exceptions.py b/bodhi/exceptions.py index f6c1607..6d0e17f 100644 --- a/bodhi/exceptions.py +++ b/bodhi/exceptions.py @@ -12,6 +12,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +from createrepo.utils import MDError + class BodhiException(Exception): pass @@ -27,7 +29,7 @@ class RPMNotFound(BodhiException): class RepositoryLocked(BodhiException): pass -class RepositoryNotFound(BodhiException): +class RepositoryNotFound(MDError): pass class InvalidRequest(BodhiException): diff --git a/bodhi/modifyrepo.py b/bodhi/modifyrepo.py index e8593ec..bbf938d 100644 --- a/bodhi/modifyrepo.py +++ b/bodhi/modifyrepo.py @@ -1,5 +1,4 @@ -# $Id: modifyrepo.py,v 1.1 2006/12/07 07:19:41 lmacken Exp $ -# +#!/usr/bin/env python # This tools is used to insert arbitrary metadata into an RPM repository. # Example: # ./modifyrepo.py updateinfo.xml myrepo/repodata @@ -18,19 +17,18 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # +# (C) Copyright 2006 Red Hat, Inc. # Luke Macken - -""" - This tool is in CVS HEAD of createrepo -""" +# modified by Seth Vidal 2008 import os import sys -import sha -import gzip + +from createrepo.utils import checksum_and_rename, GzipFile, MDError +from yum.misc import checksum from xml.dom import minidom -from bodhi.exceptions import RepositoryNotFound + class RepoMetadata: @@ -38,12 +36,15 @@ class RepoMetadata: """ Parses the repomd.xml file existing in the given repo directory. """ self.repodir = os.path.abspath(repo) self.repomdxml = os.path.join(self.repodir, 'repomd.xml') + self.checksum_type = 'sha256' if not os.path.exists(self.repomdxml): - raise RepositoryNotFound, self.repomdxml + raise MDError, '%s not found' % self.repomdxml self.doc = minidom.parse(self.repomdxml) - def _insert_element(self, parent, name, attrs={}, text=None): + def _insert_element(self, parent, name, attrs=None, text=None): child = self.doc.createElement(name) + if not attrs: + attrs = {} for item in attrs.items(): child.setAttribute(item[0], item[1]) if text: @@ -59,60 +60,79 @@ class RepoMetadata: """ md = None if not metadata: - raise Exception('metadata cannot be None') + raise MDError, 'metadata cannot be None' if isinstance(metadata, minidom.Document): md = metadata.toxml() mdname = 'updateinfo.xml' elif isinstance(metadata, str): if os.path.exists(metadata): - oldmd = file(metadata, 'r') + if metadata.endswith('.gz'): + oldmd = GzipFile(filename=metadata, mode='rb') + else: + oldmd = file(metadata, 'r') md = oldmd.read() oldmd.close() mdname = os.path.basename(metadata) else: - raise Exception('%s not found' % metadata) + raise MDError, '%s not found' % metadata else: - raise Exception('invalid metadata type') + raise MDError, 'invalid metadata type' ## Compress the metadata and move it into the repodata - mdname += '.gz' + if not mdname.endswith('.gz'): + mdname += '.gz' mdtype = mdname.split('.')[0] destmd = os.path.join(self.repodir, mdname) - newmd = gzip.GzipFile(destmd, 'wb') - newmd.write(md.encode('utf-8')) + newmd = GzipFile(filename=destmd, mode='wb') + newmd.write(md) newmd.close() print "Wrote:", destmd - ## Read the gzipped metadata - f = file(destmd, 'r') - newmd = f.read() - f.close() + open_csum = checksum(self.checksum_type, metadata) + + + csum, destmd = checksum_and_rename(destmd, self.checksum_type) + base_destmd = os.path.basename(destmd) + ## Remove any stale metadata for elem in self.doc.getElementsByTagName('data'): if elem.attributes['type'].value == mdtype: - self.doc.firstChild.removeChild(elem) + self.doc.firstChild.removeChild(elem) + ## Build the metadata root = self.doc.firstChild + root.appendChild(self.doc.createTextNode(" ")) data = self._insert_element(root, 'data', attrs={ 'type' : mdtype }) + data.appendChild(self.doc.createTextNode("\n ")) + self._insert_element(data, 'location', - attrs={ 'href' : 'repodata/' + mdname }) - self._insert_element(data, 'checksum', attrs={ 'type' : 'sha' }, - text=sha.new(newmd).hexdigest()) + attrs={ 'href' : 'repodata/' + base_destmd }) + data.appendChild(self.doc.createTextNode("\n ")) + self._insert_element(data, 'checksum', + attrs={ 'type' : self.checksum_type }, + text=csum) + data.appendChild(self.doc.createTextNode("\n ")) self._insert_element(data, 'timestamp', text=str(os.stat(destmd).st_mtime)) - self._insert_element(data, 'open-checksum', attrs={ 'type' : 'sha' }, - text=sha.new(md.encode('utf-8')).hexdigest()) + data.appendChild(self.doc.createTextNode("\n ")) + self._insert_element(data, 'open-checksum', + attrs={ 'type' : self.checksum_type }, + text=open_csum) + + data.appendChild(self.doc.createTextNode("\n ")) + root.appendChild(self.doc.createTextNode("\n")) - #print " type =", mdtype - #print " location =", 'repodata/' + mdname - #print " checksum =", sha.new(newmd).hexdigest() - #print " timestamp =", str(os.stat(destmd).st_mtime) - #print " open-checksum =", sha.new(md).hexdigest() + print " type =", mdtype + print " location =", 'repodata/' + mdname + print " checksum =", csum + print " timestamp =", str(os.stat(destmd).st_mtime) + print " open-checksum =", open_csum ## Write the updated repomd.xml outmd = file(self.repomdxml, 'w') self.doc.writexml(outmd) + outmd.write("\n") outmd.close() print "Wrote:", self.repomdxml @@ -121,6 +141,14 @@ if __name__ == '__main__': if len(sys.argv) != 3 or '-h' in sys.argv: print "Usage: %s " % sys.argv[0] sys.exit() + try: + repomd = RepoMetadata(sys.argv[2]) + except MDError, e: + print "Could not access repository: %s" % str(e) + sys.exit(1) + try: + repomd.add(sys.argv[1]) + except MDError, e: + print "Could not add metadata from file %s: %s" % (sys.argv[1], str(e)) + sys.exit(1) - repomd = RepoMetadata(sys.argv[2]) - repomd.add(sys.argv[1])