# author: Jonathan Dieter # # heavily modified from yum-deltarpm.py created by # Lars Herrmann # # 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 from yum.plugins import TYPE_INTERACTIVE, PluginYumExit from yum import config import os import sys sys.path.append("/usr/share/presto") import deltarpm from prestoRepo import PrestoRepository from prestomdparser import PrestoMDParser import prestoTransaction import prestoLog import prestoDownload requires_api_version = '2.1' LOG_FILE = "/var/log/presto.log" plugin_type = (TYPE_INTERACTIVE,) rpm_size = 0 drpm_size = 0 drpm_count = 0 log = None # Configuration stuff def config_hook(conduit): # Set up repository specific deltarpm url and mirrorlist config.RepoConf.deltaurl = config.UrlListOption() config.RepoConf.deltamirrorlist = config.UrlOption() # Add --disable-presto option parser = conduit.getOptParser() parser.add_option('', '--disablepresto', dest='disablepresto', action='store_true', default=False, help="disable Presto plugin and don't download any deltarpms") # Set up Presto repositories def postreposetup_hook(conduit): opts, commands = conduit.getCmdLine() if not opts.disablepresto: conduit.info(2, 'Setting up Presto') for active_repo in conduit.getRepos().listEnabled(): p_repo = PrestoRepository(active_repo, conduit) p_repo.setup(conduit.getConf().cache) conduit.info(2, 'Reading Presto metadata in from local files') for active_repo in conduit.getRepos().listEnabled(): xml = active_repo.p_repo.getPrestoXML() if active_repo.p_repo.enabled: xmldata = active_repo.p_repo.repoXML.getData('deltas') (ctype, csum) = xmldata.checksum parser = PrestoMDParser(xml) active_repo.p_repo.deltalist = parser.getDeltaList() else: conduit.info(5, '--disablepresto specified - Presto disabled') def postresolve_hook(conduit): global rpm_size global drpm_size global drpm_count opts, commands = conduit.getCmdLine() if not opts.disablepresto: # Cycle through packages to see if there's a deltarpm available for newpkg in conduit.getTsInfo(): if newpkg.ts_state != "e": (chosen_drpm, installed, local, drpm_enabled) = prestoTransaction.find_available_drpms(conduit, newpkg) # If a drpm was found, change certain package information so it reflects # the drpm, not the rpm. if chosen_drpm != None: newpkg.po.has_drpm = True conduit.info(2, "Found deltarpm update for %s.%s %s:%s-%s" % (newpkg.name, newpkg.arch, newpkg.epoch, newpkg.version, newpkg.release)) # In yum 3.0.x, this doesn't get defined if you run "yum update x" rather than "yum update" rpm_size += int(newpkg.po.size) drpm_size += int(chosen_drpm['size']) newpkg.po.realpackagesize = newpkg.po.size if hasattr(newpkg.po, 'packagesize'): newpkg.po.packagesize = chosen_drpm['size'] else: newpkg.po.simple['packagesize'] = chosen_drpm['size'] newpkg.po.deltasize = chosen_drpm['size'] newpkg.po.deltarelativepath = chosen_drpm['drpm_filename'] newpkg.po.deltachecksumtype = chosen_drpm['checksum_type'] newpkg.po.deltachecksum = chosen_drpm['checksum'] newpkg.po.deltalocalpath = newpkg.po.repo.deltasdir + "/" + os.path.basename(chosen_drpm['drpm_filename']) newpkg.po.to = newpkg newpkg.po.hasdrpm = True newpkg.repoid = newpkg.po.repo.id + " *" drpm_count += 1 else: if installed and drpm_enabled and not local: try: rpm_size += int(newpkg.po.size) drpm_size += int(newpkg.po.size) except: pass return def predownload_hook(conduit): global drpm_count global log # Set up logging log = prestoLog.PrestoLog(conduit, LOG_FILE) pkglist = conduit.getDownloadPackages() opts, commands = conduit.getCmdLine() if not opts.disablepresto and drpm_count > 0: conduit.info(2, "Downloading DeltaRPMs:") # Download deltarpms problems = prestoDownload.downloadPkgs(conduit, pkglist, log) # If 'exitondownloaderror' is on, exit if conduit.confBool('main', 'exitondownloaderror') and len(problems.keys()) > 0: errstring = 'Error Downloading Packages:\n' for key in problems.keys(): errors = misc.unique(problems[key]) for error in errors: errstring += ' %s: %s\n' % (key, error) raise PluginYumExit(errstring) else: conduit.info(2, "Downloading RPMs:") def posttrans_hook(conduit): global rpm_size global drpm_size global log log.close() if rpm_size > 0: drpm_string = prestoTransaction.format_number(drpm_size) rpm_string = prestoTransaction.format_number(rpm_size) conduit.info(2, "Size of all updates downloaded from Presto-enabled repositories: %s" % drpm_string) conduit.info(2, "Size of updates that would have been downloaded if Presto wasn't enabled: %s" % rpm_string) conduit.info(2, "This is a savings of %i percent" % (100 - ((drpm_size * 100) / rpm_size)))