2 # This tools is used to insert arbitrary metadata into an RPM repository.
4 # ./modifyrepo.py updateinfo.xml myrepo/repodata
6 # >>> from modifyrepo import RepoMetadata
7 # >>> repomd = RepoMetadata('myrepo/repodata')
8 # >>> repomd.add('updateinfo.xml')
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # (C) Copyright 2006 Red Hat, Inc.
21 # Luke Macken <lmacken@redhat.com>
22 # modified by Seth Vidal 2008
26 from createrepo import __version__
27 from createrepo.utils import checksum_and_rename, GzipFile, MDError
28 from yum.misc import checksum
30 from yum.repoMDObject import RepoMD, RepoMDError, RepoData
31 from xml.dom import minidom
32 from optparse import OptionParser
37 def __init__(self, repo):
38 """ Parses the repomd.xml file existing in the given repo directory. """
39 self.repodir = os.path.abspath(repo)
40 self.repomdxml = os.path.join(self.repodir, 'repomd.xml')
41 self.checksum_type = 'sha256'
43 if not os.path.exists(self.repomdxml):
44 raise MDError, '%s not found' % self.repomdxml
47 self.repoobj = RepoMD(self.repodir)
48 self.repoobj.parse(self.repomdxml)
49 except RepoMDError, e:
50 raise MDError, 'Could not parse %s' % self.repomdxml
53 def add(self, metadata, mdtype=None):
54 """ Insert arbitrary metadata into this repository.
55 metadata can be either an xml.dom.minidom.Document object, or
60 raise MDError, 'metadata cannot be None'
61 if isinstance(metadata, minidom.Document):
63 mdname = 'updateinfo.xml'
64 elif isinstance(metadata, str):
65 if os.path.exists(metadata):
66 if metadata.endswith('.gz'):
67 oldmd = GzipFile(filename=metadata, mode='rb')
69 oldmd = file(metadata, 'r')
72 mdname = os.path.basename(metadata)
74 raise MDError, '%s not found' % metadata
76 raise MDError, 'invalid metadata type'
78 ## Compress the metadata and move it into the repodata
79 if not mdname.endswith('.gz'):
82 mdtype = mdname.split('.')[0]
84 destmd = os.path.join(self.repodir, mdname)
85 newmd = GzipFile(filename=destmd, mode='wb')
88 print "Wrote:", destmd
90 open_csum = checksum(self.checksum_type, metadata)
91 csum, destmd = checksum_and_rename(destmd, self.checksum_type)
92 base_destmd = os.path.basename(destmd)
95 ## Remove any stale metadata
96 if mdtype in self.repoobj.repoData:
97 del self.repoobj.repoData[mdtype]
102 new_rd.location = (None, 'repodata/' + base_destmd)
103 new_rd.checksum = (self.checksum_type, csum)
104 new_rd.openchecksum = (self.checksum_type, open_csum)
105 new_rd.size = str(os.stat(destmd).st_size)
106 new_rd.timestamp = str(os.stat(destmd).st_mtime)
107 self.repoobj.repoData[new_rd.type] = new_rd
109 print " type =", new_rd.type
110 print " location =", new_rd.location[1]
111 print " checksum =", new_rd.checksum[1]
112 print " timestamp =", new_rd.timestamp
113 print " open-checksum =", new_rd.openchecksum[1]
115 ## Write the updated repomd.xml
116 outmd = file(self.repomdxml, 'w')
117 outmd.write(self.repoobj.dump_xml())
119 print "Wrote:", self.repomdxml
123 parser = OptionParser(version='modifyrepo version %s' % __version__)
125 parser.add_option("--mdtype", dest='mdtype',
126 help="specific datatype of the metadata, will be derived from the filename if not specified")
127 parser.usage = "modifyrepo [options] <input_metadata> <output repodata>"
129 (opts, argsleft) = parser.parse_args(args)
130 if len(argsleft) != 2:
133 metadata = argsleft[0]
134 repodir = argsleft[1]
136 repomd = RepoMetadata(repodir)
138 print "Could not access repository: %s" % str(e)
141 repomd.add(metadata, mdtype=opts.mdtype)
143 print "Could not add metadata from file %s: %s" % (metadata, str(e))
146 if __name__ == '__main__':
147 ret = main(sys.argv[1:])