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

Source Code for Module bodhi.closure

  1  # $Id: closure.py,v 1.5 2006/11/12 21:04:47 lmacken Exp $ 
  2  # 
  3  # This program is free software; you can redistribute it and/or modify 
  4  # it under the terms of the GNU General Public License as published by 
  5  # the Free Software Foundation; version 2 of the License. 
  6  # 
  7  # This program is distributed in the hope that it will be useful, 
  8  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  9  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 10  # GNU Library General Public License for more details. 
 11  # 
 12  # You should have received a copy of the GNU General Public License 
 13  # along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 15  # 
 16   
 17  # for debugging 
 18  import pdb 
 19  from pprint import pprint 
 20   
 21  import os 
 22  import sys 
 23  import time 
 24  import glob 
 25  import string 
 26  import logging 
 27  import tempfile 
 28  import turbogears 
 29   
 30  from os.path import join, exists, walk, normpath, isdir 
 31  from bodhi.model import PackageUpdate 
 32  from turbogears import config 
 33  from yum.constants import * 
 34   
 35  sys.path.append('/usr/share/createrepo') 
 36  import genpkgmetadata 
 37   
 38  # pull in RepoClosure 
 39  execfile('/usr/bin/repoclosure') 
 40   
 41  log = logging.getLogger(__name__) 
 42   
 43  confheader = """ 
 44  [main] 
 45  cachedir=%s 
 46  debuglevel=2 
 47  logfile=/var/log/yum.log 
 48  pkgpolicy=newest 
 49  distroverpkg=fedora-release 
 50  reposdir=/dev/null 
 51  """ 
 52   
 53  repo_config = """ 
 54  [core-%(rel)s-%(arch)s] 
 55  name=Fedora Core %(rel)s - %(arch)s 
 56  baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/%(rel)s/%(arch)s/os/ 
 57  enabled=1 
 58   
 59  [updates %(rel)s-%(arch)s] 
 60  name=Fedora Core Updates %(rel)s - %(arch)s 
 61  baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/updates/%(rel)s/%(arch)s/ 
 62  enabled=1 
 63   
 64  [updates-testing %(rel)s-%(arch)s] 
 65  name=Fedora Core Updates Testing %(rel)s - %(arch)s 
 66  baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/updates/testing/%(rel)s/%(arch)s/ 
 67  enabled=%(testing)s 
 68   
 69  [testrepo-%(rel)s-%(arch)s] 
 70  name=Fedora Core %(rel)s - %(arch)s 
 71  baseurl=file://%(testrepo)s/final/%(rel)s/%(arch)s 
 72  enabled=%(final)s 
 73   
 74  [testrepo-testing-%(rel)s-%(arch)s] 
 75  name=Fedora Core %(rel)s - %(arch)s 
 76  baseurl=file://%(testrepo)s/testing/%(rel)s/%(arch)s 
 77  enabled=%(testing)s 
 78  """ 
 79   
80 -class TestRepoClosure:
81
82 - def __init__(self, updates):
83 self.updates = updates 84 self.testing = False 85 self.final = False 86 self.testrepo_dir = config.get('testrepo_dir') 87 self.cache_dir = config.get('createrepo_cache_dir') 88 89 # set our cache directory 90 global confheader 91 confheader %= self.cache_dir 92 93 # create a set of releases that we need to check closure on 94 self.releases = set() 95 for update in self.updates: 96 if update.testing: 97 self.testing = True 98 else: 99 self.final = True 100 self.releases.add(update.release)
101
102 - def run(self):
103 """ 104 Prepare the closure repo, and begin the test 105 """ 106 log.debug("Running TestRepoClosure") 107 start = time.time() 108 109 self._clean() 110 self._copy_to_repo() 111 self._generate_metadata() 112 113 # Run repoclosure on the given repos. 114 for release in self.releases: 115 log.debug("Checking Dependecies for %s" % release.name) 116 self._test_closure(release) 117 118 log.debug("Dependency checking complete in %f seconds" % ( 119 time.time()- start))
120
121 - def _copy_to_repo(self):
122 """ 123 Copy the files to the test repository 124 """ 125 log.debug("Copying update packages to our test repo") 126 for update in self.updates: 127 oldreq = update.request 128 update.request = 'push' 129 for msg in update.run_request(self.testrepo_dir): 130 log.debug(msg) 131 update.request = oldreq
132
133 - def _clean(self):
134 """ 135 Wipe out the existing testrepo and create the appropriate repo 136 directories for this batch of updates. 137 """ 138 import shutil 139 log.debug("Cleaning the closure repository") 140 if exists(self.testrepo_dir): 141 log.debug("Removing old test repo tree") 142 shutil.rmtree(self.testrepo_dir) 143 for update in self.updates: 144 repo = join(self.testrepo_dir, update.get_repo()) 145 for arch in update.release.arches: 146 archdir = join(repo, arch.name) 147 srpmdir = join(repo, 'SRPMS') 148 if not exists(archdir): 149 log.debug("Creating " + archdir) 150 os.makedirs(join(archdir, 'debug')) 151 if not exists(srpmdir): 152 log.debug("Creating " + srpmdir) 153 os.mkdir(srpmdir)
154
155 - def _generate_metadata(self):
156 """ 157 Build the repository metadata and config file 158 """ 159 for tf in ('testing', ''): 160 for release in os.listdir(join(self.testrepo_dir, tf)): 161 if release == 'testing': continue 162 for arch in os.listdir(join(self.testrepo_dir, tf, release)): 163 fullpath = normpath(join(self.testrepo_dir, tf, 164 release,arch)) 165 log.debug("Generating metadata for %s" % fullpath) 166 genpkgmetadata.main(['-c', str(self.cache_dir), '-q', 167 str(fullpath)])
168
169 - def _test_closure(self, release):
170 """ 171 Run repoclosure on for a given release 172 """ 173 for arch in release.arches: 174 for testing in (True, False): 175 log.debug("Checking closure on %s-%s-%s" % (release.name, 176 arch.name, testing and 'testing' or 'final')) 177 if not self.testing and testing: 178 log.debug("Skipping updates-testing check for %s - %s" % 179 (release.name, arch.name)) 180 continue 181 conf = self.generate_config(release, arch, testing) 182 log.debug("Using yum configuration = %s" % conf) 183 closure = RepoClosure(config = conf) 184 log.debug("Reading Metadata()") 185 closure.readMetadata() 186 log.debug("Checking for broken deps") 187 baddeps = closure.getBrokenDeps(newest=True) 188 log.debug("Broken deps:") 189 pkgs = baddeps.keys() 190 pkgs.sort() 191 for pkg in pkgs: 192 log.debug('[%s]' % pkg) 193 for (n, f, v) in baddeps[pkg]: 194 r = '%s' % n 195 if f: 196 flag = LETTERFLAGS[f] 197 r = '%s %s' % (r, flag) 198 if v: 199 r = '%s %s' % (r, v) 200 log.debug(' * %s' % r)
201
202 - def generate_config(self, release, arch, testing):
203 """ 204 Generate a yum configuration file for this given release containing 205 the core repo, both updates and updates-testing for each arch that 206 this release supports 207 """ 208 conffile = tempfile.mktemp() 209 fd = open(conffile, 'w') 210 fd.write(confheader) 211 repo = repo_config % { 212 'testrepo' : self.testrepo_dir, 213 'rel' : release.repodir, 214 'arch' : arch.name, 215 'testing' : testing and '1' or '0', 216 'final' : self.final and '1' or '0' 217 } 218 fd.write(repo) 219 fd.close() 220 return conffile
221 222 # 223 # Main method used for testing purposes 224 # 225 if __name__ == '__foo__': 226 from turbogears.database import PackageHub 227 228 hub = PackageHub("bodhi") 229 __connection__ = hub 230 231 log = logging.getLogger(__name__) 232 log.setLevel(logging.DEBUG) 233 234 closure = TestRepoClosure(PackageUpdate.select()) 235 closure.run() 236