dcavalca / rpms / dnf

Forked from rpms/dnf 2 years ago
Clone

Blame SOURCES/1743.patch

fa73ac
From 054cd9db81af13b5cdc669067775ff71aa82625f Mon Sep 17 00:00:00 2001
fa73ac
From: Matthew Almond <malmond@fb.com>
fa73ac
Date: Tue, 9 Mar 2021 11:01:40 -0800
fa73ac
Subject: [PATCH 1/2] Use libdnf.utils.checksum_{check,value}
fa73ac
fa73ac
libdnf has the canonical implementation of checksum handling. We aim to
fa73ac
replace all use of dnf.yum.misc.checksum() with this. In doing so, this
fa73ac
fixes installing previously downloaded and transcoded rpms to support
fa73ac
fa73ac
https://github.com/rpm-software-management/librepo/pull/222
fa73ac
fa73ac
This also has some minor performance benefits: librepo's checksum
fa73ac
handling employs caching of previously downloaded files via extended
fa73ac
attributes. This works for ordinary rpms in the dnf cache, but does not
fa73ac
work (yet) for rpm paths specified on the command line due to
fa73ac
https://github.com/rpm-software-management/librepo/issues/233. That
fa73ac
issue is pretty minor, and the fix ends up in libdnf later.
fa73ac
fa73ac
The previous implementation maps all runtime errors to MiscError. We do
fa73ac
this still by taking the libdnf.error.Error class (defined in SWIG) and
fa73ac
map it directly back to the Python exception as before.
fa73ac
---
fa73ac
 dnf/package.py  |  18 ++++----
fa73ac
 dnf/yum/misc.py | 113 ------------------------------------------------
fa73ac
 2 files changed, 10 insertions(+), 121 deletions(-)
fa73ac
fa73ac
diff --git a/dnf/package.py b/dnf/package.py
fa73ac
index b01e555eba..fc89cf98a8 100644
fa73ac
--- a/dnf/package.py
fa73ac
+++ b/dnf/package.py
fa73ac
@@ -30,6 +30,8 @@
fa73ac
 import dnf.rpm
fa73ac
 import dnf.yum.misc
fa73ac
 import hawkey
fa73ac
+import libdnf.error
fa73ac
+import libdnf.utils
fa73ac
 import logging
fa73ac
 import os
fa73ac
 import rpm
fa73ac
@@ -56,7 +58,10 @@ def _chksum(self):
fa73ac
             return self._priv_chksum
fa73ac
         if self._from_cmdline:
fa73ac
             chksum_type = dnf.yum.misc.get_default_chksum_type()
fa73ac
-            chksum_val = dnf.yum.misc.checksum(chksum_type, self.location)
fa73ac
+            try:
fa73ac
+                chksum_val = libdnf.utils.checksum_value(chksum_type, self.location)
fa73ac
+            except libdnf.error.Error as e:
fa73ac
+                raise dnf.exceptions.MiscError(str(e))
fa73ac
             return (hawkey.chksum_type(chksum_type),
fa73ac
                     binascii.unhexlify(chksum_val))
fa73ac
         return super(Package, self).chksum
fa73ac
@@ -330,10 +335,7 @@ def verifyLocalPkg(self):
fa73ac
         if self._from_cmdline:
fa73ac
             return True # local package always verifies against itself
fa73ac
         (chksum_type, chksum) = self.returnIdSum()
fa73ac
-        real_sum = dnf.yum.misc.checksum(chksum_type, self.localPkg(),
fa73ac
-                                         datasize=self._size)
fa73ac
-        if real_sum != chksum:
fa73ac
-            logger.debug(_('%s: %s check failed: %s vs %s'),
fa73ac
-                         self, chksum_type, real_sum, chksum)
fa73ac
-            return False
fa73ac
-        return True
fa73ac
+        try:
fa73ac
+            return libdnf.utils.checksum_check(chksum_type, self.localPkg(), chksum)
fa73ac
+        except libdnf.error.Error as e:
fa73ac
+            raise dnf.exceptions.MiscError(str(e))
fa73ac
diff --git a/dnf/yum/misc.py b/dnf/yum/misc.py
fa73ac
index 3e3905feb8..af018a8a1b 100644
fa73ac
--- a/dnf/yum/misc.py
fa73ac
+++ b/dnf/yum/misc.py
fa73ac
@@ -22,7 +22,6 @@
fa73ac
 
fa73ac
 from __future__ import print_function, absolute_import
fa73ac
 from __future__ import unicode_literals
fa73ac
-from dnf.exceptions import MiscError
fa73ac
 from dnf.pycomp import base64_decodebytes, basestring, unicode
fa73ac
 from stat import *
fa73ac
 import libdnf.utils
fa73ac
@@ -32,7 +31,6 @@
fa73ac
 import dnf.i18n
fa73ac
 import errno
fa73ac
 import glob
fa73ac
-import hashlib
fa73ac
 import io
fa73ac
 import os
fa73ac
 import os.path
fa73ac
@@ -41,7 +39,6 @@
fa73ac
 import shutil
fa73ac
 import tempfile
fa73ac
 
fa73ac
-_available_checksums = set(['md5', 'sha1', 'sha256', 'sha384', 'sha512'])
fa73ac
 _default_checksums = ['sha256']
fa73ac
 
fa73ac
 
fa73ac
@@ -68,119 +65,9 @@ def re_full_search_needed(s):
fa73ac
             return True
fa73ac
     return False
fa73ac
 
fa73ac
-
fa73ac
-class Checksums(object):
fa73ac
-    """ Generate checksum(s), on given pieces of data. Producing the
fa73ac
-        Length and the result(s) when complete. """
fa73ac
-
fa73ac
-    def __init__(self, checksums=None, ignore_missing=False, ignore_none=False):
fa73ac
-        if checksums is None:
fa73ac
-            checksums = _default_checksums
fa73ac
-        self._sumalgos = []
fa73ac
-        self._sumtypes = []
fa73ac
-        self._len = 0
fa73ac
-
fa73ac
-        done = set()
fa73ac
-        for sumtype in checksums:
fa73ac
-            if sumtype == 'sha':
fa73ac
-                sumtype = 'sha1'
fa73ac
-            if sumtype in done:
fa73ac
-                continue
fa73ac
-
fa73ac
-            if sumtype in _available_checksums:
fa73ac
-                sumalgo = hashlib.new(sumtype)
fa73ac
-            elif ignore_missing:
fa73ac
-                continue
fa73ac
-            else:
fa73ac
-                raise MiscError('Error Checksumming, bad checksum type %s' %
fa73ac
-                                sumtype)
fa73ac
-            done.add(sumtype)
fa73ac
-            self._sumtypes.append(sumtype)
fa73ac
-            self._sumalgos.append(sumalgo)
fa73ac
-        if not done and not ignore_none:
fa73ac
-            raise MiscError('Error Checksumming, no valid checksum type')
fa73ac
-
fa73ac
-    def __len__(self):
fa73ac
-        return self._len
fa73ac
-
fa73ac
-    # Note that len(x) is assert limited to INT_MAX, which is 2GB on i686.
fa73ac
-    length = property(fget=lambda self: self._len)
fa73ac
-
fa73ac
-    def update(self, data):
fa73ac
-        self._len += len(data)
fa73ac
-        for sumalgo in self._sumalgos:
fa73ac
-            data = data.encode('utf-8') if isinstance(data, unicode) else data
fa73ac
-            sumalgo.update(data)
fa73ac
-
fa73ac
-    def read(self, fo, size=2**16):
fa73ac
-        data = fo.read(size)
fa73ac
-        self.update(data)
fa73ac
-        return data
fa73ac
-
fa73ac
-    def hexdigests(self):
fa73ac
-        ret = {}
fa73ac
-        for sumtype, sumdata in zip(self._sumtypes, self._sumalgos):
fa73ac
-            ret[sumtype] = sumdata.hexdigest()
fa73ac
-        return ret
fa73ac
-
fa73ac
-    def hexdigest(self, checksum=None):
fa73ac
-        if checksum is None:
fa73ac
-            if not self._sumtypes:
fa73ac
-                return None
fa73ac
-            checksum = self._sumtypes[0]
fa73ac
-        if checksum == 'sha':
fa73ac
-            checksum = 'sha1'
fa73ac
-        return self.hexdigests()[checksum]
fa73ac
-
fa73ac
-    def digests(self):
fa73ac
-        ret = {}
fa73ac
-        for sumtype, sumdata in zip(self._sumtypes, self._sumalgos):
fa73ac
-            ret[sumtype] = sumdata.digest()
fa73ac
-        return ret
fa73ac
-
fa73ac
-    def digest(self, checksum=None):
fa73ac
-        if checksum is None:
fa73ac
-            if not self._sumtypes:
fa73ac
-                return None
fa73ac
-            checksum = self._sumtypes[0]
fa73ac
-        if checksum == 'sha':
fa73ac
-            checksum = 'sha1'
fa73ac
-        return self.digests()[checksum]
fa73ac
-
fa73ac
 def get_default_chksum_type():
fa73ac
     return _default_checksums[0]
fa73ac
 
fa73ac
-def checksum(sumtype, file, CHUNK=2**16, datasize=None):
fa73ac
-    """takes filename, hand back Checksum of it
fa73ac
-       sumtype = md5 or sha/sha1/sha256/sha512 (note sha == sha1)
fa73ac
-       filename = /path/to/file
fa73ac
-       CHUNK=65536 by default"""
fa73ac
-
fa73ac
-    # chunking brazenly lifted from Ryan Tomayko
fa73ac
-
fa73ac
-    if isinstance(file, basestring):
fa73ac
-        try:
fa73ac
-            with open(file, 'rb', CHUNK) as fo:
fa73ac
-                return checksum(sumtype, fo, CHUNK, datasize)
fa73ac
-        except (IOError, OSError):
fa73ac
-            raise MiscError('Error opening file for checksum: %s' % file)
fa73ac
-
fa73ac
-    try:
fa73ac
-        # assumes file is a file-like-object
fa73ac
-        data = Checksums([sumtype])
fa73ac
-        while data.read(file, CHUNK):
fa73ac
-            if datasize is not None and data.length > datasize:
fa73ac
-                break
fa73ac
-
fa73ac
-        # This screws up the length, but that shouldn't matter. We only care
fa73ac
-        # if this checksum == what we expect.
fa73ac
-        if datasize is not None and datasize != data.length:
fa73ac
-            return '!%u!%s' % (datasize, data.hexdigest(sumtype))
fa73ac
-
fa73ac
-        return data.hexdigest(sumtype)
fa73ac
-    except (IOError, OSError) as e:
fa73ac
-        raise MiscError('Error reading file for checksum: %s' % file)
fa73ac
-
fa73ac
 class GenericHolder(object):
fa73ac
     """Generic Holder class used to hold other objects of known types
fa73ac
        It exists purely to be able to do object.somestuff, object.someotherstuff
fa73ac