# 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 from yum.plugins import TYPE_INTERACTIVE 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 requires_api_version = '2.1' plugin_type = (TYPE_INTERACTIVE,) # Setup repository specific deltarpm url and mirrorlist def config_hook(conduit): config.RepoConf.deltaurl = config.UrlListOption() config.RepoConf.deltamirrorlist = config.UrlOption() # Set up Presto repositories def prereposetup_hook(conduit): 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() conduit.info(2, 'Setting up repositories') def postresolve_hook(conduit): # Cycle through packages to see if there's a deltarpm available for newpkg in conduit.getTsInfo(): if newpkg.ts_state != "e": chosen_drpm = 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.hasdrpm = True newpkg.po.simple['basepath'] = chosen_drpm['baseurl'] newpkg.po.simple['realpackagesize'] = newpkg.po.simple['packagesize'] newpkg.po.simple['packagesize'] = chosen_drpm['size'] newpkg.po.simple['realrelativepath'] = newpkg.po.simple['relativepath'] newpkg.po.simple['relativepath'] = chosen_drpm['drpm_filename'] newpkg.po.reallocalpath = newpkg.po.localpath newpkg.po.localpath = newpkg.po.repo.deltasdir + "/" + os.path.basename(chosen_drpm['drpm_filename']) newpkg.po.to = newpkg newpkg.realpkgtup = newpkg.pkgtup newpkg.pkgtup = (newpkg.name + " *", newpkg.arch, newpkg.epoch, newpkg.version, newpkg.release) for (csum_type, csum, csumid) in newpkg.po._checksums: if csumid: newpkg.po._realchecksum = (csum_type, csum, csumid) newpkg.po._checksums.remove((csum_type, csum, csumid)) csum_type = chosen_drpm['checksum_type'] csum = chosen_drpm['checksum'] newpkg.po._checksums.append((csum_type, csum, csumid)) conduit.info(2, "Found deltarpm update for %s.%s %s:%s.%s" % (newpkg.name, newpkg.arch, newpkg.epoch, newpkg.version, newpkg.release)) else: newpkg.po.hasdrpm = False return # Free up memory used by deleting Presto repositories for active_repo in conduit.getRepos().listEnabled(): if active_repo.p_repo.enabled: del active_repo.p_repo def postdownload_hook(conduit): # Cycle through packages to see if we've downloaded a deltarpm conduit.info(2, "Rebuilding full packages from deltas") for pkg in conduit.getDownloadPackages(): if pkg.hasdrpm and pkg.verifyLocalPkg(): # Apply deltarpm and save where rpm would have been saved drpm = deltarpm.DeltaRpmWrapper(conduit) drpm.apply(pkg.reallocalpath, pkg.localpath) drpm_path = pkg.localpath # Change package information to reflect original rpm information pkg.to.pkgtup = pkg.to.realpkgtup pkg.localpath = pkg.reallocalpath pkg.simple['packagesize'] = pkg.simple['realpackagesize'] del pkg.simple['basepath'] for (csum_type, csum, csumid) in pkg._checksums: if csumid: pkg._checksums.remove((csum_type, csum, csumid)) pkg._checksums.append(pkg._realchecksum) # Check to see whether or not we should keep the drpms # FIXME: Is there any way to see whether or not a Boolean option was not set? if conduit.confBool('main', 'neverkeepdeltas'): delete = True elif conduit.confBool('main', 'keepdeltas'): delete = False elif conduit.getConf().keepcache != 0: delete = False else: delete = True if delete: os.unlink(drpm_path)