summaryrefslogtreecommitdiffstats
path: root/presto.py
blob: 454d3724a7fd6f30a1da641aa088ccf02599296c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# author: Jonathan Dieter <jdieter@gmail.com>
#
# heavily modified from yum-deltarpm.py created by
#         Lars Herrmann <herrmann@redhat.com>
# 
# 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['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
    for pkg in conduit.getDownloadPackages():
        if pkg.hasdrpm:
            # 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']
            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)