From 551d28b7ed7a098cf14a7e8a023c4606726ade31 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: May 12 2017 08:23:33 +0000 Subject: Add robosignatory-signmodule cli command Signed-off-by: Jan Kaluza --- diff --git a/robosignatory/cli.py b/robosignatory/cli.py index d9e6241..1cecdac 100644 --- a/robosignatory/cli.py +++ b/robosignatory/cli.py @@ -79,3 +79,14 @@ def atomicsigner(): val = config['robosignatory.ostree_refs'][ref] robosignatory.work.process_atomic(signer, ref, commitid, **val) + +def modulesigner(): + if len(sys.argv) != 3: + print 'Usage: %s ' % sys.argv[0] + sys.exit(1) + + koji_instance = sys.argv[1] + tag = sys.argv[2] + + signer = TagSignerConsumer(None) + signer.sign_modular_tag(koji_instance, tag) diff --git a/robosignatory/tagconsumer.py b/robosignatory/tagconsumer.py index a77b02c..65e609e 100644 --- a/robosignatory/tagconsumer.py +++ b/robosignatory/tagconsumer.py @@ -304,8 +304,9 @@ class TagSignerConsumer(fedmsg.consumers.FedmsgConsumer): tag_info = instance['tags'][tag] - log.info('Going to sign with %s (%s) and move to %s', - tag_info['key'], tag_info['keyid'], tag_info['to']) + log.info('Going to sign %s with %s (%s) and move to %s', + build_nvr, tag_info['key'], tag_info['keyid'], + tag_info['to']) rpms = utils.get_rpms(instance['client'], build_nvr=build_nvr, @@ -354,3 +355,35 @@ class TagSignerConsumer(fedmsg.consumers.FedmsgConsumer): else: instance['client'].tagBuild(tag_info['to'], build_id, False, tag) + + def sign_modular_tag(self, koji_instance, tag): + """ + Signs all the latest RPMs in a modular tag + """ + if koji_instance not in self.koji_clients: + log.error('Koji instance not known.') + return + + # Get the list of all builds in the tag. + instance = self.koji_clients[koji_instance] + builds = utils.get_builds_in_tag(instance["client"], tag) + if not builds: + log.info("No build to sign in given tag.") + return + + # Try signing the first build. This queries the PDC to find out + # the base module for a build and therefore is slow. Therefore + # we do that only for the first build. In the end it adds the + # resulting signing key to instance["tags"] cache and that is what + # we use for the rest of builds in this module. + self.sign_modular_rpms(builds[0]["nvr"], builds[0]["build_id"], tag, + koji_instance) + if tag not in instance["tags"] or not instance["tags"][tag]: + # No need to log anything, sign_module_rpms logs an error + # when it cannot sign a module build. + return + + # Sign the rest of builds in tag. + for build in builds[1:]: + self.dowork(build["nvr"], build["build_id"], tag, koji_instance, + skip_tagging=False) diff --git a/robosignatory/utils.py b/robosignatory/utils.py index e78616b..b86afa7 100644 --- a/robosignatory/utils.py +++ b/robosignatory/utils.py @@ -1,6 +1,7 @@ import abc import pkg_resources import subprocess +import koji import logging log = logging.getLogger('robosignatory.utils') @@ -25,6 +26,18 @@ def get_rpms(koji_client, build_nvr=None, build_id=None, sigkey=None): rpminfo['%s.%s' % (rpm['nvr'], rpm['arch'])] = info return rpminfo +def get_builds_in_tag(koji_client, tag): + """ Return the list of builds in Koji tag. """ + + try: + rpms, builds = koji_client.listTaggedRPMS(tag, latest=True) + except koji.GenericError as e: + log.exception("Failed to list rpms in tag %r" % tag) + # If the tag doesn't exist.. then there are no rpms in that tag. + return [] + + return builds + def run_command(command): child = subprocess.Popen(command, stdin=subprocess.PIPE, diff --git a/setup.py b/setup.py index 80b6cc9..2999a28 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,7 @@ setup( robosignatory-signbuild = robosignatory.cli:buildsigner robosignatory-signtagbuild = robosignatory.cli:tagsigner robosignatory-signatomic = robosignatory.cli:atomicsigner + robosignatory-signmodule = robosignatory.cli:modulesigner [robosignatory.signing.helpers] echo = robosignatory.utils:EchoHelper