[elbe-devel] [PATCH v2 1/3] elbepack: make package hash handling more flexible

Thomas Weißschuh thomas.weissschuh at linutronix.de
Tue Jun 18 12:04:46 CEST 2024


Instead of hardcoding only md5 and sha256 hashes switch to more flexible
aproach.
This makes the code shorter and easier to extend to additional hash
algorithms.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh at linutronix.de>
---
 elbepack/aptpkgutils.py | 58 +++++++++++++++++++++++++------------------------
 elbepack/dump.py        | 30 ++++++++++---------------
 elbepack/elbexml.py     | 11 +++++-----
 3 files changed, 47 insertions(+), 52 deletions(-)

diff --git a/elbepack/aptpkgutils.py b/elbepack/aptpkgutils.py
index fdfecec36958..90fc2c7a8a7c 100644
--- a/elbepack/aptpkgutils.py
+++ b/elbepack/aptpkgutils.py
@@ -27,22 +27,25 @@ statestring = {
 }
 
 
-def apt_pkg_md5(pkg):
-    hashes = pkg._records.hashes
-    for i in range(len(hashes)):
-        h = str(hashes[i])
-        if h.startswith('MD5'):
-            return h.split(':')[1]
-    return ''
+# Mapping from apt_pkg.HashString to elbe xml
+_apt_hash_mapping = {
+    'MD5Sum': 'md5',
+    'SHA256': 'sha256',
+}
+
+
+def _apt_pkg_hashes(pkg):
+    r = {}
 
+    for h in pkg._records.hashes:
+        t = _apt_hash_mapping.get(h.hashtype)
+        if t is None:
+            continue
 
-def apt_pkg_sha256(pkg):
-    hashes = pkg._records.hashes
-    for i in range(len(hashes)):
-        h = str(hashes[i])
-        if h.startswith('SHA256'):
-            return h.split(':')[1]
-    return ''
+        assert t not in r
+        r[t] = h.hashvalue
+
+    return r
 
 
 def getdeps(pkg):
@@ -197,18 +200,15 @@ class PackageBase:
 
     def __init__(self, name,
                  installed_version, candidate_version,
-                 installed_md5, candidate_md5,
-                 installed_sha256, candidate_sha256,
+                 installed_hashes, candidate_hashes,
                  installed_prio, candidate_prio,
                  state, is_auto_installed, origin, architecture):
 
         self.name = name
         self.installed_version = installed_version
         self.candidate_version = candidate_version
-        self.installed_md5 = installed_md5
-        self.candidate_md5 = candidate_md5
-        self.installed_sha256 = installed_sha256
-        self.candidate_sha256 = candidate_sha256
+        self.installed_hashes = installed_hashes
+        self.candidate_hashes = candidate_hashes
         self.installed_prio = installed_prio
         self.candidate_prio = candidate_prio
         self.state = state
@@ -234,10 +234,8 @@ class APTPackage(PackageBase):
 
         iver = pkg.installed and pkg.installed.version
         cver = pkg.candidate and pkg.candidate.version
-        imd5 = pkg.installed and apt_pkg_md5(pkg.installed)
-        cmd5 = pkg.candidate and apt_pkg_md5(pkg.candidate)
-        isha256 = pkg.installed and apt_pkg_sha256(pkg.installed)
-        csha256 = pkg.candidate and apt_pkg_sha256(pkg.candidate)
+        ihashes = pkg.installed and _apt_pkg_hashes(pkg.installed)
+        chashes = pkg.candidate and _apt_pkg_hashes(pkg.candidate)
         iprio = pkg.installed and pkg.installed.priority
         cprio = pkg.candidate and pkg.candidate.priority
 
@@ -258,8 +256,7 @@ class APTPackage(PackageBase):
 
         PackageBase.__init__(self, pkg.name,
                              iver, cver,
-                             imd5, cmd5,
-                             isha256, csha256,
+                             ihashes, chashes,
                              iprio, cprio,
                              pkgstate(pkg), pkg.is_auto_installed,
                              origin, arch)
@@ -267,10 +264,15 @@ class APTPackage(PackageBase):
 
 class XMLPackage(PackageBase):
     def __init__(self, node, arch):
+        hashes = {}
+        for h in _apt_hash_mapping.keys():
+            v = node.et.get(h)
+            if v is not None:
+                hashes[h] = v
+
         PackageBase.__init__(self, node.et.text,
                              node.et.get('version'), None,
-                             node.et.get('md5'), None,
-                             node.et.get('sha256'), None,
+                             hashes, None,
                              node.et.get('prio'), None,
                              INSTALLED, node.et.get('auto') == 'true',
                              None, arch)
diff --git a/elbepack/dump.py b/elbepack/dump.py
index 1c0a4ea84428..3edb715b8238 100644
--- a/elbepack/dump.py
+++ b/elbepack/dump.py
@@ -10,7 +10,7 @@ from fnmatch import fnmatchcase
 
 from apt import Cache
 
-from elbepack.aptpkgutils import APTPackage
+from elbepack.aptpkgutils import APTPackage, XMLPackage
 from elbepack.archivedir import archive_tmpfile
 from elbepack.finetuning import do_finetuning
 from elbepack.shellhelper import do
@@ -120,10 +120,9 @@ def check_full_pkgs(pkgs, fullpkgs, cache):
 
     pindex = {}
     for p in fullpkgs:
+        xml_pkg = XMLPackage(p)
         name = p.et.text
         ver = p.et.get('version')
-        md5 = p.et.get('md5')
-        sha256 = p.et.get('sha256')
 
         pindex[name] = p
 
@@ -145,22 +144,16 @@ def check_full_pkgs(pkgs, fullpkgs, cache):
             errors += 1
             continue
 
-        if md5:
-            if pkg.installed_md5 != md5:
-                validation.error("Package '%s' md5 %s does not match installed md5 %s",
-                                 name, md5, pkg.installed_md5)
-                errors += 1
-
-        if sha256:
-            if pkg.installed_sha256 != sha256:
-                validation.error("Package '%s' sha256 %s does not match installed sha256 %s",
-                                 name, sha256, pkg.installed_sha256)
-                errors += 1
-
-        if not md5 and not sha256:
+        if not xml_pkg.installed_hashes:
             validation.error("Package '%s' has no hash setup in package list.",
                              name)
             errors += 1
+        else:
+            for k, v in xml_pkg.installed_hashes:
+                if v != pkg.installed_hashes[k]:
+                    validation.error("Package '%s' %s %s does not match installed %s %s",
+                                     name, k, v, k, pkg.installed_hashes[k])
+                    errors += 1
 
     for cp in cache.get_installed_pkgs():
         if cp.name not in pindex:
@@ -302,13 +295,14 @@ def elbe_report(xml, buildenv, cache, targetfs):
         f = targetfs.open('etc/elbe_pkglist', 'w')
     for pkg in tgt_pkg_list:
         p = pkgindex[pkg]
+        hashes = ','.join(p.installed_hashes.values())
         report.info('|%s|%s|%s|%s',
                     p.name,
                     p.installed_version,
                     p.is_auto_installed,
-                    p.installed_md5)
+                    hashes)
         if xml.has('target/pkgversionlist'):
-            f.write(f'{p.name} {p.installed_version} {p.installed_md5}\n')
+            f.write(f'{p.name} {p.installed_version} {hashes}\n')
 
     if xml.has('target/pkgversionlist'):
         f.close()
diff --git a/elbepack/elbexml.py b/elbepack/elbexml.py
index 11c2b3f7e44f..175026bac1f8 100644
--- a/elbepack/elbexml.py
+++ b/elbepack/elbexml.py
@@ -387,16 +387,15 @@ class ElbeXML:
         pak.et.tail = '\n'
         if aptpkg.installed_version is not None:
             pak.et.set('version', aptpkg.installed_version)
-            if aptpkg.installed_md5:
-                pak.et.set('md5', aptpkg.installed_md5)
-            pak.et.set('sha256', aptpkg.installed_sha256)
             pak.et.set('prio', aptpkg.installed_prio)
+            hashes = aptpkg.installed_hashes
         else:
             pak.et.set('version', aptpkg.candidate_version)
-            if aptpkg.candidate_md5:
-                pak.et.set('md5', aptpkg.candidate_md5)
-            pak.et.set('sha256', aptpkg.candidate_sha256)
             pak.et.set('prio', aptpkg.candidate_prio)
+            hashes = aptpkg.candidate_hashes
+
+        for k, v in hashes.items():
+            pak.et.set(k, v)
 
         if aptpkg.is_auto_installed:
             pak.et.set('auto', 'true')

-- 
2.45.2



More information about the elbe-devel mailing list