From 5b8e64253027eb98a30f072658802d0e83fb43dc Mon Sep 17 00:00:00 2001
From: Tomas Kopecek <tkopecek@redhat.com>
Date: Aug 29 2018 12:13:36 +0000
Subject: consolidate access to rpm headers


Fixes: https://pagure.io/koji/issue/1069

---

diff --git a/builder/kojid b/builder/kojid
index 06c14e7..b10ba89 100755
--- a/builder/kojid
+++ b/builder/kojid
@@ -605,7 +605,7 @@ class BuildRoot(object):
         try:
             ts = rpm.TransactionSet()
             for h in ts.dbMatch():
-                pkg = koji.get_header_fields(h,fields)
+                pkg = koji.get_header_fields(h, fields)
                 #skip our fake packages
                 if pkg['name'] in ['buildsys-build', 'gpg-pubkey']:
                     #XXX config
@@ -922,7 +922,7 @@ class BuildTask(BaseTaskHandler):
             self.event_id = self.session.getLastEvent()['id']
         srpm = self.getSRPM(src, build_tag, repo_info['id'])
         h = self.readSRPMHeader(srpm)
-        data = koji.get_header_fields(h,['name','version','release','epoch'])
+        data = koji.get_header_fields(h, ['name','version','release','epoch'])
         data['task_id'] = self.id
         if getattr(self, 'source', False):
             data['source'] = self.source['source']
@@ -1009,7 +1009,7 @@ class BuildTask(BaseTaskHandler):
         fo = koji.openRemoteFile(relpath, **opts)
         h = koji.get_rpm_header(fo)
         fo.close()
-        if h[rpm.RPMTAG_SOURCEPACKAGE] != 1:
+        if koji.get_header_field(h , 'sourcepackage'):
             raise koji.BuildError("%s is not a source package" % srpm)
         return h
 
@@ -1028,9 +1028,9 @@ class BuildTask(BaseTaskHandler):
         archlist = arches.split()
         self.logger.debug('base archlist: %r' % archlist)
         # - adjust arch list based on srpm macros
-        buildarchs = h[rpm.RPMTAG_BUILDARCHS]
-        exclusivearch = h[rpm.RPMTAG_EXCLUSIVEARCH]
-        excludearch = h[rpm.RPMTAG_EXCLUDEARCH]
+        buildarchs = koji.get_header_field(h, 'buildarchs')
+        exclusivearch = koji.get_header_field(h, 'exclusivearch')
+        excludearch = koji.get_header_field(h, 'excludearch')
         if buildarchs:
             archlist = buildarchs
             self.logger.debug('archlist after buildarchs: %r' % archlist)
@@ -1071,8 +1071,8 @@ class BuildTask(BaseTaskHandler):
         # see https://pagure.io/koji/issue/19
 
         h = self.readSRPMHeader(srpm)
-        exclusivearch = h[rpm.RPMTAG_EXCLUSIVEARCH]
-        excludearch = h[rpm.RPMTAG_EXCLUDEARCH]
+        exclusivearch = koji.get_header_field(h, 'exclusivearch')
+        excludearch = koji.get_header_field(h, 'excludearch')
 
         if exclusivearch or excludearch:
             # if one of the tag arches is filtered out, then we can't use a
@@ -1218,11 +1218,11 @@ class BuildArchTask(BaseBuildTask):
     def srpm_sanity_checks(self, filename):
         header = koji.get_rpm_header(filename)
 
-        if not header[rpm.RPMTAG_PACKAGER]:
+        if not koji.get_header_field(header, 'packager'):
             raise koji.BuildError("The build system failed to set the packager tag")
-        if not header[rpm.RPMTAG_VENDOR]:
+        if not koji.get_header_field(header, 'vendor'):
             raise koji.BuildError("The build system failed to set the vendor tag")
-        if not header[rpm.RPMTAG_DISTRIBUTION]:
+        if not koji.get_header_field(header, 'distribution'):
             raise koji.BuildError("The build system failed to set the distribution tag")
 
     def handler(self, pkg, root, arch, keep_srpm, opts=None):
@@ -1243,15 +1243,12 @@ class BuildArchTask(BaseBuildTask):
             raise koji.BuildError("SRPM file missing: %s" % fn)
         # peel E:N-V-R from package
         h = koji.get_rpm_header(fn)
-        name = h[rpm.RPMTAG_NAME]
-        ver = h[rpm.RPMTAG_VERSION]
-        rel = h[rpm.RPMTAG_RELEASE]
-        epoch = h[rpm.RPMTAG_EPOCH]
-        if h[rpm.RPMTAG_SOURCEPACKAGE] != 1:
+        name = koji.get_header_field(h, 'name')
+        if koji.get_header_field(h, 'sourcepackage'):
             raise koji.BuildError("not a source package")
         # Disable checking for distribution in the initial SRPM because it
         # might have been built outside of the build system
-        # if not h[rpm.RPMTAG_DISTRIBUTION]:
+        # if not koji.get_header_field(h, 'distribution'):
         #    raise koji.BuildError, "the distribution tag is not set in the original srpm"
 
         self.updateWeight(name)
@@ -4641,9 +4638,9 @@ class BuildSRPMFromSCMTask(BaseBuildTask):
 
         # check srpm name
         h = koji.get_rpm_header(srpm)
-        name = h[rpm.RPMTAG_NAME]
-        version = h[rpm.RPMTAG_VERSION]
-        release = h[rpm.RPMTAG_RELEASE]
+        name = koji.get_header_field(h, 'name')
+        version = koji.get_header_field(h, 'version')
+        release = koji.get_header_field(h, 'release')
         srpm_name = "%(name)s-%(version)s-%(release)s.src.rpm" % locals()
         if srpm_name != os.path.basename(srpm):
             raise koji.BuildError('srpm name mismatch: %s != %s' % (srpm_name, os.path.basename(srpm)))
diff --git a/hub/kojihub.py b/hub/kojihub.py
index 2364d0a..5c0e23e 100644
--- a/hub/kojihub.py
+++ b/hub/kojihub.py
@@ -5362,7 +5362,7 @@ def import_rpm(fn, buildinfo=None, brootid=None, wrapper=False, fileinfo=None):
     rpminfo['id'] = _singleValue("""SELECT nextval('rpminfo_id_seq')""")
     rpminfo['build_id'] = buildinfo['id']
     rpminfo['size'] = os.path.getsize(fn)
-    rpminfo['payloadhash'] = koji.hex_string(hdr[rpm.RPMTAG_SIGMD5])
+    rpminfo['payloadhash'] = koji.hex_string(koji.get_header_field(hdr, 'sigmd5'))
     rpminfo['buildroot_id'] = brootid
     rpminfo['external_repo_id'] = 0
 
@@ -6570,10 +6570,10 @@ def _scan_sighdr(sighdr, fn):
     #(we have no payload, so verifies would fail otherwise)
     hdr = ts.hdrFromFdno(outp.fileno())
     outp.close()
-    sig = hdr[rpm.RPMTAG_SIGGPG]
+    sig = koji.get_header_field(hdr, 'siggpg')
     if not sig:
-        sig = hdr[rpm.RPMTAG_SIGPGP]
-    return hdr[rpm.RPMTAG_SIGMD5], sig
+        sig = koji.get_header_field(hdr, 'sigpgp')
+    return koji.get_header_field(hdr, 'sigmd5'), sig
 
 def check_rpm_sig(an_rpm, sigkey, sighdr):
     #verify that the provided signature header matches the key and rpm
@@ -6600,9 +6600,9 @@ def check_rpm_sig(an_rpm, sigkey, sighdr):
         except:
             pass
         raise
-    raw_key = hdr[rpm.RPMTAG_SIGGPG]
+    raw_key = koji.get_header_field(hdr, 'siggpg')
     if not raw_key:
-        raw_key = hdr[rpm.RPMTAG_SIGPGP]
+        raw_key = koji.get_header_field(hdr, 'sigpgp')
     if not raw_key:
         found_key = None
     else:
diff --git a/koji/__init__.py b/koji/__init__.py
index 8786063..516ca15 100644
--- a/koji/__init__.py
+++ b/koji/__init__.py
@@ -894,6 +894,21 @@ def get_rpm_header(f, ts=None):
     return hdr
 
 
+def _decode_item(item):
+     """Decode rpm header byte strings to str in py3"""
+     if six.PY2:
+         return item
+     elif isinstance(item, bytes):
+         try:
+             return item.decode()
+         except UnicodeDecodeError:
+             # typically signatures
+             return item
+     elif isinstance(item, list):
+         return [_decode_item(x) for x in item]
+     else:
+         return item
+
 def get_header_field(hdr, name, src_arch=False):
     """Extract named field from an rpm header"""
     name = name.upper()
@@ -917,12 +932,8 @@ def get_header_field(hdr, name, src_arch=False):
             result = []
         elif isinstance(result, six.integer_types):
             result = [result]
-    if six.PY3 and isinstance(result, bytes):
-        try:
-            result = result.decode('utf-8')
-        except UnicodeDecodeError:
-            # typically signatures
-            pass
+
+    result = _decode_item(result)
 
     sizetags = ('SIZE', 'ARCHIVESIZE', 'FILESIZES', 'SIGSIZE')
     if name in sizetags and (result is None or result == []):
diff --git a/tests/test_hub/test_dist_repo.py b/tests/test_hub/test_dist_repo.py
index e0637b1..8540e1f 100644
--- a/tests/test_hub/test_dist_repo.py
+++ b/tests/test_hub/test_dist_repo.py
@@ -204,6 +204,7 @@ class TestDistRepoMove(unittest.TestCase):
 
 
     def test_distRepoMove(self):
+        kojihub.context.session = mock.MagicMock()
         exports = kojihub.HostExports()
         exports.distRepoMove(self.rinfo['id'], self.uploadpath, self.arch)
         # check result

