Trees | Indices | Help |
---|
|
1 # $Id: metadata.py,v 1.1 2006/12/31 09:10:14 lmacken Exp $ 2 # This program is free software; you can redistribute it and/or modify 3 # it under the terms of the GNU General Public License as published by 4 # the Free Software Foundation; version 2 of the License. 5 # 6 # This program is distributed in the hope that it will be useful, 7 # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 # GNU Library General Public License for more details. 10 # 11 # You should have received a copy of the GNU General Public License 12 # along with this program; if not, write to the Free Software 13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 14 15 __version__ = '1.4' 16 17 import os 18 import rpm 19 import gzip 20 import logging 21 import commands 22 23 from xml.dom import minidom 24 from os.path import join, basename, exists, isdir 25 from sqlobject import SQLObjectNotFound 26 from turbogears import config 27 28 from bodhi.util import get_repo_tag 29 from bodhi.model import PackageBuild 30 from bodhi.buildsys import get_session 31 from bodhi.modifyrepo import RepoMetadata 32 from bodhi.exceptions import RepositoryNotFound 33 34 log = logging.getLogger(__name__) 353721639 self.tag = get_repo_tag(repo) 40 self.repo = repo 41 self.doc = None 42 self.updates = set() 43 self.builds = {} 44 self.checksums = {} # { pkg-ver-rel : { arch : checksum, ... }, ... } 45 self.koji = get_session() 46 self._create_document() 47 self._fetch_updates() 48 self._fetch_checksums() 49 log.debug("Generating XML update metadata for updates") 50 map(self.add_update, self.updates)5153 """ 54 Based on our given koji tag, populate a list of PackageUpdates. 55 """ 56 log.debug("Fetching builds tagged with '%s'" % self.tag) 57 kojiBuilds = self.koji.listTagged(self.tag, latest=True) 58 log.debug("%d builds found" % len(kojiBuilds)) 59 for build in kojiBuilds: 60 self.builds[build['nvr']] = build 61 try: 62 b = PackageBuild.byNvr(build['nvr']) 63 map(self.updates.add, b.updates) 64 except SQLObjectNotFound, e: 65 log.warning(e)6668 log.debug("Creating new updateinfo Document for %s" % self.tag) 69 self.doc = minidom.Document() 70 updates = self.doc.createElement('updates') 71 self.doc.appendChild(updates)7274 """ Helper function to trivialize inserting an element into the doc """ 75 child = self.doc.createElement(name) 76 for item in attrs.items(): 77 child.setAttribute(item[0], str(item[1])) 78 if text: 79 txtnode = self.doc.createTextNode(str(text)) 80 child.appendChild(txtnode) 81 parent.appendChild(child) 82 return child8385 for elem in self.doc.getElementsByTagName('update'): 86 for child in elem.childNodes: 87 if child.nodeName == 'id' and child.firstChild and \ 88 child.firstChild.nodeValue == update.update_id: 89 return elem 90 return None9193 """ 94 Pull a list of 'name-version-release sha1' from our repodata and store 95 it in self.checksums = { n-v-r : { arch : sha1sum } } 96 """ 97 log.debug("Fetching checksums from repodata") 98 for arch in os.listdir(self.repo): 99 archrepo = join(self.repo, arch) 100 if not isdir(archrepo): continue 101 cmd = 'repoquery --repofrompath=foo,%s --repofrompath=bar,%s -a --qf "%%{name}-%%{version}-%%{release} %%{id}" --repoid=foo --repoid=bar' % (archrepo, join(archrepo, 'debug')) 102 log.debug("Running `%s`" % cmd) 103 out = commands.getoutput(cmd) 104 try: 105 for line in out.split('\n')[2:]: 106 pkg, csum = line.split() 107 if not self.checksums.has_key(pkg): 108 self.checksums[pkg] = {} 109 self.checksums[pkg][arch] = csum 110 except Exception, e: 111 log.error("Unable to parse repoquery output: %s" % e)112 113 #def remove_update(self, update): 114 # elem = self._get_notice(update) 115 # if elem: 116 # log.debug("Removing %s from updateinfo.xml" % update.title) 117 # self.doc.firstChild.removeChild(elem) 118 # return True 119 # return False 120122 """ 123 Generate the extended metadata for a given update 124 """ 125 ## Make sure this update doesn't already exist 126 if self._get_notice(update): 127 log.debug("Update %s already in updateinfo" % update.title) 128 return 129 130 log.debug("Generating extended metadata for %s" % update.title) 131 132 root = self._insert(self.doc.firstChild, 'update', attrs={ 133 'type' : update.type, 134 'status' : update.status, 135 'version' : __version__, 136 'from' : config.get('release_team_address') 137 }) 138 139 self._insert(root, 'id', text=update.update_id) 140 self._insert(root, 'title', text=update.title) 141 self._insert(root, 'release', text=update.release.long_name) 142 self._insert(root, 'issued', attrs={ 'date' : update.date_pushed }) 143 144 ## Build the references 145 refs = self.doc.createElement('references') 146 for cve in update.cves: 147 self._insert(refs, 'reference', attrs={ 148 'type' : 'cve', 149 'href' : cve.get_url(), 150 'id' : cve.cve_id 151 }) 152 for bug in update.bugs: 153 self._insert(refs, 'reference', attrs={ 154 'type' : 'bugzilla', 155 'href' : bug.get_url(), 156 'id' : bug.bz_id, 157 'title': bug.title 158 }) 159 root.appendChild(refs) 160 161 ## Errata description 162 self._insert(root, 'description', text=update.notes) 163 164 ## The package list 165 pkglist = self.doc.createElement('pkglist') 166 collection = self.doc.createElement('collection') 167 collection.setAttribute('short', update.release.name) 168 self._insert(collection, 'name', text=update.release.long_name) 169 170 for build in update.builds: 171 log.debug("Generating package list for %s" % build.nvr) 172 kojiBuild = self.builds[build.nvr] 173 rpms = self.koji.listBuildRPMs(kojiBuild['id']) 174 for rpm in rpms: 175 filename = "%s.%s.rpm" % (rpm['nvr'], rpm['arch']) 176 if rpm['arch'] == 'src': 177 arch = 'SRPMS' 178 elif rpm['arch'] == 'noarch': 179 arch = 'i386' 180 else: 181 arch = rpm['arch'] 182 urlpath = join(config.get('file_url'), 183 update.status == 'testing' and 'testing' or '', 184 update.release.name[-1], arch, filename) 185 pkg = self._insert(collection, 'package', attrs={ 186 'name' : rpm['name'], 187 'version' : rpm['version'], 188 'release' : rpm['release'], 189 'arch' : rpm['arch'], 190 'src' : urlpath 191 }) 192 self._insert(pkg, 'filename', text=filename) 193 try: 194 self._insert(pkg, 'sum', attrs={ 'text' : 'sha1' }, 195 text=self.checksums[rpm['nvr']][arch]) 196 except KeyError: 197 log.error("Unable to find checksum for %s" % rpm['nvr']) 198 199 if build.package.suggest_reboot: 200 self._insert(pkg, 'reboot_suggested', text='True') 201 202 collection.appendChild(pkg) 203 204 pkglist.appendChild(collection) 205 root.appendChild(pkglist) 206 log.debug("Metadata generation successful")207209 for arch in os.listdir(self.repo): 210 try: 211 repomd = RepoMetadata(join(self.repo, arch, 'repodata')) 212 log.debug("Inserting updateinfo.xml.gz into %s" % self.repo) 213 repomd.add(self.doc) 214 except RepositoryNotFound: 215 log.error("Cannot find repomd.xml in %s" % self.repo)
Trees | Indices | Help |
---|
Generated by Epydoc 3.0beta1 on Sun Sep 23 14:46:35 2007 | http://epydoc.sourceforge.net |