# author: Jonathan Dieter # # format_number taken almost completely from progress_meter.py in yum # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Copyright 2005 Duke University # Copyright 2007 Jonathan Dieter import os import deltarpm def format_number(number, SI=False, space=''): """Turn numbers into human-readable metric-like numbers""" symbols = ['', # (none) 'K', # kilo 'M', # mega 'G', # giga 'T', # tera 'P', # peta 'E', # exa 'Z', # zetta 'Y'] # yotta if SI: step = 1000.0 else: step = 1024.0 thresh = 999 depth = 0 # we want numbers between while number > thresh: depth = depth + 1 number = number / step # just in case someone needs more than 1000 yottabytes! diff = depth - len(symbols) + 1 if diff > 0: depth = depth - diff number = number * thresh**depth if type(number) == type(1) or type(number) == type(1L): format = '%i%s%s' elif number < 9.95: # must use 9.95 for proper sizing. For example, 9.99 will be # rounded to 10.0 with the .1f format string (which is too long) format = '%.1f%s%s' else: format = '%.0f%s%s' return(format % (number, space, symbols[depth])) def find_available_drpms(conduit, newpkg): """Find any applicable drpms for newpkg newpkg is a TransactionMember""" rpmdb = conduit.getRpmDB() is_local = False # Set p_repo to be packages delta repository or set to False if # there is no delta repository try: p_repo = newpkg.po.repo.p_repo drpm_enabled = p_repo.enabled po = newpkg.po if hasattr(po, 'pkgtype') and po.pkgtype == 'local': is_local = True else: local = po.localPkg() if os.path.exists(local): cursize = os.stat(local)[6] totsize = long(po.size) if not po.verifyLocalPkg(): if cursize >= totsize: # otherwise keep it around for regetting os.unlink(local) else: conduit.info(5, "using local copy of %s" % po) is_local = True except: conduit.info(5, "No Presto repository information for %s.%s %i:%s-%s" % (newpkg.name, newpkg.arch, int(newpkg.epoch), newpkg.version, newpkg.release)) drpm_enabled = False is_local = False chosen_drpm = None # First part of key when matching drpms key1 = "%s*%s*%i*%s*%s" % (newpkg.name, newpkg.arch, int(newpkg.epoch), newpkg.version, newpkg.release) # Find any installed packages that match the ones we want to download installed = rpmdb.searchNevra(newpkg.name, None, None, None, newpkg.arch) if installed == []: is_installed = False else: is_installed = True if is_installed and drpm_enabled and not is_local: for oldpkg in installed: # Generate second part of key for matching drpms, then full key key2 = "%s*%s*%i*%s*%s" % (oldpkg.name, oldpkg.arch, int(oldpkg.epoch), oldpkg.version, oldpkg.release) key = "%s!!%s" % (key1, key2) # Check whether we have a matching drpm if p_repo.deltalist.has_key(key): # Check whether or not we already have a matching drpm, then choose smallest of the two if we do if chosen_drpm == None or p_repo.deltalist[key]['size'] < chosen_drpm['size']: # Get sequence code for drpm sequence = p_repo.deltalist[key]['sequence'] # if int(oldpkg.epoch) == 0: # Don't try to save space on sequence anymore. It just won't work. # seq = "%s-%s-%s-%s" % (oldpkg.name, oldpkg.version, oldpkg.release, sequence) # else: # seq = "%s-%i:%s-%s-%s" % (oldpkg.name, int(oldpkg.epoch), oldpkg.version, oldpkg.release, sequence) drpm = deltarpm.DeltaRpmWrapper(conduit) # Attempt to apply sequence code for drpm. If this fails, drpm will not apply cleanly, so # don't even try to download it. try: drpm.verifySequence(sequence) except: conduit.info(5, "Verification of %s failed" % seq) else: chosen_drpm = p_repo.deltalist[key] chosen_drpm['baseurl'] = p_repo.baseurl[0] newpkg.po.oldpkg_string = "%s.%s %s:%s-%s" % (oldpkg.name, oldpkg.arch, oldpkg.epoch, oldpkg.version, oldpkg.release) newpkg.po.newpkg_string = "%s.%s %s:%s-%s" % (newpkg.name, newpkg.arch, newpkg.epoch, newpkg.version, newpkg.release) return (chosen_drpm, installed, is_local, drpm_enabled)