From 3b7633eb1cde911ad8cd03654572b9ba554a6534 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sep 16 2025 13:39:58 +0000 Subject: [PATCH 1/2] fully honor sigkey option in import-sig command --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index 7eaf77f..d437cf7 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -1732,20 +1732,24 @@ def handle_import_sig(goptions, session, args): 'sourcepackage')) if data['sourcepackage']: data['arch'] = 'src' - sigkey = data['siggpg'] - if not sigkey: - sigkey = data['sigpgp'] - if not sigkey: - sigkey = data['dsaheader'] - if not sigkey: - sigkey = data['rsaheader'] - if not sigkey: - sigkey = "" - if not options.with_unsigned: - print("Skipping unsigned package: %s" % path) - continue + if options.sigkey is not None: + sigkey = options.sigkey else: - sigkey = koji.get_sigpacket_key_id(sigkey) + # calculate from header values + sigkey = data['siggpg'] + if not sigkey: + sigkey = data['sigpgp'] + if not sigkey: + sigkey = data['dsaheader'] + if not sigkey: + sigkey = data['rsaheader'] + if not sigkey: + sigkey = "" + if not options.with_unsigned: + print("Skipping unsigned package: %s" % path) + continue + else: + sigkey = koji.get_sigpacket_key_id(sigkey) del data['siggpg'] del data['sigpgp'] del data['dsaheader'] @@ -1774,6 +1778,7 @@ def handle_import_sig(goptions, session, args): kwargs = {} if options.sigkey: kwargs['sigkey'] = options.sigkey + # if sigkey is not specified, the hub will calculate from the header, similar to above print("Importing signature [key %s] from %s..." % (sigkey, path)) if not options.test: session.addRPMSig(rinfo['id'], base64encode(sighdr), **kwargs) From ae1bb9c655f853e6f00f9231e04bbdc9a3b1f47c Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sep 16 2025 13:39:58 +0000 Subject: [PATCH 2/2] add unit test --- diff --git a/tests/test_cli/test_import_sig.py b/tests/test_cli/test_import_sig.py index c95d43d..e5dfb5f 100644 --- a/tests/test_cli/test_import_sig.py +++ b/tests/test_cli/test_import_sig.py @@ -286,6 +286,42 @@ class TestImportSIG(utils.CliTestCase): self.session.addRPMSig.assert_not_called() self.session.writeSignedRPM.assert_not_called() + @mock.patch('sys.stdout', new_callable=six.StringIO) + def test_handle_import_sig_sigkey_specified(self, stdout): + """Test sigkey computation from header-only signed rpm in handle_import_sig function""" + data_path = os.path.abspath("tests/test_hub/data/rpms") + sigkey = 'OVERRIDE' + rpms = [os.path.join(data_path, 'header-signed.rpm')] + arguments = ['--sigkey', sigkey] + rpms + + expected = '' + + for pkg in rpms: + expected += "Importing signature [key %s] from %s..." % (sigkey, pkg) + "\n" + expected += "Writing signed copy" + "\n" + + rpminfo = { + 'sourcepackage': 0, + 'name': 'testpkg', + 'version': '1.0.0', + 'release': '1', + 'arch': 'x86_64', + 'external_repo_id': 0, + 'id': 1, + } + self.session.getRPM.side_effect = [rpminfo] + self.session.queryRPMSigs.side_effect = None + self.session.queryRPMSigs.return_value = [] + + # Run + handle_import_sig(self.options, self.session, arguments) + + self.assert_console_message(stdout, expected) + self.session.addRPMSig.assert_called_once() + kw1 = self.session.addRPMSig.call_args_list[0][1] + self.assertEqual(kw1, {'sigkey': sigkey}) + self.session.writeSignedRPM.assert_called_once_with(rpminfo['id'], sigkey) + def test_handle_import_sig_argument_test(self): """Test handle_import_sig function without arguments""" # Case 1. empty argument