---
 yum/__init__.py | 39 ++++++++++++++-----------
 yum/drpm.py     | 88 +++++++++++++++++++++++++++++++--------------------------
 2 files changed, 70 insertions(+), 57 deletions(-)

diff --git a/yum/__init__.py b/yum/__init__.py
index 71e1a70..f61431f 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -90,7 +90,7 @@ from packages import YumUrlPackage, YumNotFoundPackage
 from constants import *
 from yum.rpmtrans import RPMTransaction,SimpleCliCallBack
 from yum.i18n import to_unicode, to_str, exception2msg
-from yum.drpm import DeltaInfo
+from yum.drpm import DeltaInfo, DeltaPO
 
 import string
 import StringIO
@@ -2183,7 +2183,7 @@ much more problems).
             b = bpo.getDiscNum()
             if a is None and b is None:
                 # deltas first to start rebuilding asap
-                return cmp(bpo in presto.deltas, apo in presto.deltas) \
+                return cmp(isinstance(bpo, DeltaPO), isinstance(apo, DeltaPO)) 
\
                     or cmp(apo, bpo)
             if a is None:
                 return -1
@@ -2249,19 +2249,22 @@ much more problems).
                 return errors
             pkgs.append(po)
 
-        # download presto metadata
+        # download presto metadata and use drpms
         presto = DeltaInfo(self, pkgs)
+        deltasize = rpmsize = 0
         for po in pkgs:
-            if presto.to_drpm(po) and verify_local(po):
-                # there's .drpm already, use it
-                presto.rebuild(po, adderror)
-                continue
+            if isinstance(po, DeltaPO):
+                if verify_local(po):
+                    # there's .drpm already, use it
+                    presto.rebuild(po, adderror)
+                    continue
+                deltasize += po.size
+                rpmsize = po.rpm.size
             remote_pkgs.append(po)
             remote_size += po.size
-        if presto.deltasize:
+        if deltasize:
             self.verbose_logger.info(_('Delta RPMs reduced %s of updates to %s 
(%d%% saved)'),
-                format_number(presto.rpmsize), format_number(presto.deltasize),
-                100 - presto.deltasize*100.0/presto.rpmsize)
+                format_number(rpmsize), format_number(deltasize), 100 - 
deltasize*100.0/rpmsize)
 
         if downloadonly:
             # close DBs, unlock
@@ -2290,7 +2293,7 @@ much more problems).
                     if hasattr(urlgrabber.progress, 'text_meter_total_size'):
                         urlgrabber.progress.text_meter_total_size(remote_size,
                                                                   
local_size[0])
-                    if po in presto.deltas:
+                    if isinstance(po, DeltaPO):
                         presto.rebuild(po, adderror)
                         return
                     if po.repoid not in done_repos:
@@ -2347,19 +2350,21 @@ much more problems).
                     
             fatal = False
             for po in errors:
-                if po not in presto.deltas:
-                    fatal = True; break
+                if not isinstance(po, DeltaPO):
+                    fatal = True
+                    break
             if not errors or fatal:
                 break
 
             # there were drpm related errors *only*
-            remote_pkgs = errors.keys()
+            remote_pkgs = []
             remote_size = 0
-            for po in remote_pkgs:
-                presto.to_rpm(po) # needed, we don't rebuild() when DL fails
+            for po in errors:
+                po = po.rpm
+                remote_pkgs.append(po)
                 remote_size += po.size
+            errors.clear()
             self.verbose_logger.warn(_('Some delta RPMs failed to download or 
rebuild. Retrying..'))
-            presto.deltas.clear() # any error is now considered fatal
 
         if not downloadonly:
             # XXX: Run unlocked?  Skip this for now..
diff --git a/yum/drpm.py b/yum/drpm.py
index 81afe80..96a04fd 100644
--- a/yum/drpm.py
+++ b/yum/drpm.py
@@ -20,6 +20,8 @@
 from yum.constants import TS_UPDATE
 from yum.Errors import RepoError
 from yum.i18n import exception2msg, _
+from yum.Errors import MiscError
+from misc import checksum
 from urlgrabber import grabber
 async = hasattr(grabber, 'parallel_wait')
 from xml.etree.cElementTree import iterparse
@@ -27,25 +29,56 @@ import os, gzip
 
 APPLYDELTA = '/usr/bin/applydeltarpm'
 
+class DeltaPO:
+    def __init__(self, rpm, size, remote, csum):
+        # copy what needed
+        self.rpm = rpm
+        self.repo = rpm.repo
+        self.basepath = rpm.basepath
+        self.pkgtup = rpm.pkgtup
+
+        # set up drpm attributes
+        self.size = size
+        self.relativepath = remote
+        self.localpath = os.path.dirname(rpm.localpath) +'/'+ 
os.path.basename(remote)
+        self.csum = csum
+
+    def __str__(self):
+        return 'Delta RPM of %s' % self.rpm
+
+    def localPkg(self):
+        return self.localpath
+
+    def verifyLocalPkg(self):
+        # check file size first
+        try: fsize = os.path.getsize(self.localpath)
+        except OSError: return False
+        if fsize != self.size: return False
+
+        # checksum
+        ctype, csum = self.csum
+        try: fsum = checksum(ctype, self.localpath)
+        except MiscError: return False
+        if fsum != csum: return False
+
+        # hooray
+        return True
+
 class DeltaInfo:
     def __init__(self, ayum, pkgs):
         self.verbose_logger = ayum.verbose_logger
-        self.deltas = {}
-        self._rpmsave = {}
-        self.rpmsize = 0
-        self.deltasize = 0
         self.jobs = {}
         self.limit = ayum.conf.deltarpm
 
         # calculate update sizes
         pinfo = {}
         reposize = {}
-        for po in pkgs:
+        for index, po in enumerate(pkgs):
             if not po.repo.deltarpm:
                 continue
             if po.state != TS_UPDATE and po.name not in 
ayum.conf.installonlypkgs:
                 continue
-            pinfo.setdefault(po.repo, {})[po.pkgtup] = po
+            pinfo.setdefault(po.repo, {})[po.pkgtup] = index
             reposize[po.repo] = reposize.get(po.repo, 0) + po.size
 
         # don't use deltas when deltarpm not installed
@@ -90,8 +123,9 @@ class DeltaInfo:
             for ev, el in iterparse(path):
                 if el.tag != 'newpackage': continue
                 new = el.get('name'), el.get('arch'), el.get('epoch'), 
el.get('version'), el.get('release')
-                po = pinfo_repo.get(new)
-                if po:
+                index = pinfo_repo.get(new)
+                if index is not None:
+                    po = pkgs[index]
                     best = po.size * 0.75 # make this configurable?
                     have = ayum._up.installdict.get(new[:2], [])
                     for el in el.findall('delta'):
@@ -100,34 +134,12 @@ class DeltaInfo:
                         if size >= best or old not in have:
                             continue
                         best = size
+                        remote = el.find('filename').text
                         csum = el.find('checksum')
                         csum = csum.get('type'), csum.text
-                        self.deltas[po] = size, el.find('filename').text, csum
+                        pkgs[index] = DeltaPO(po, size, remote, csum)
                 el.clear()
 
-    def to_drpm(self, po):
-        try: size, remote, csum = self.deltas[po]
-        except KeyError: return False
-        self._rpmsave[po] = po.packagesize, po.relativepath, po.localpath
-
-        # update stats
-        self.rpmsize += po.packagesize
-        self.deltasize += size
-
-        # update size/path/checksum to drpm values
-        po.packagesize = size
-        po.relativepath = remote
-        po.localpath = os.path.dirname(po.localpath) +'/'+ 
os.path.basename(remote)
-        po.returnIdSum = lambda: csum
-        return True
-
-    def to_rpm(self, po):
-        if po not in self._rpmsave:
-            return
-        # revert back to RPM
-        po.packagesize, po.relativepath, po.localpath = self._rpmsave.pop(po)
-        del po.returnIdSum
-
     def wait(self, limit = 1):
         # wait for some jobs, run callbacks
         while len(self.jobs) >= limit:
@@ -139,20 +151,16 @@ class DeltaInfo:
             callback(code)
 
     def rebuild(self, po, adderror):
-        # restore rpm values
-        deltapath = po.localpath
-        po.packagesize, po.relativepath, po.localpath = self._rpmsave.pop(po)
-        del po.returnIdSum
-
         # this runs when worker finishes
         def callback(code):
             if code != 0:
                 return adderror(po, _('Delta RPM rebuild failed'))
-            if not po.verifyLocalPkg():
+            if not po.rpm.verifyLocalPkg():
                 return adderror(po, _('Checksum of the delta-rebuilt RPM 
failed'))
-            os.unlink(deltapath)
+            os.unlink(po.localpath)
+            po.localpath = po.rpm.localpath # for --downloadonly
 
         # spawn a worker process
         self.wait(self.limit)
-        pid = os.spawnl(os.P_NOWAIT, APPLYDELTA, APPLYDELTA, deltapath, 
po.localpath)
+        pid = os.spawnl(os.P_NOWAIT, APPLYDELTA, APPLYDELTA, po.localpath, 
po.rpm.localpath)
         self.jobs[pid] = callback
-- 
1.7.11.7

_______________________________________________
Yum-devel mailing list
[email protected]
http://lists.baseurl.org/mailman/listinfo/yum-devel

Reply via email to