Hello,<br><br>Thank you for your Koji callback.<br><br>I perform some modifications:<br>+ to handle DEFAULT section (if section for Tag name is not defined)<br>+ to support empty GPG pass-phrase<br>+ to work on localized OS<br>
+ to log GPG messages if rpm --resign fails <br><br>Note: your GPG directory (gpg_path in .conf file) must be readable and writeable by apache (the user which runs Koji hub)<br><br>Regards,<br>Pierre<br>
<br># Koji callback for GPG signing RPMs before import<br>#<br># Author:<br>#     Paul B Schroeder &lt;paulbsch &quot;at&quot; vbridges &quot;dot&quot; com&gt;<br><br>from koji.plugin import register_callback<br>import logging<br>
<br># Configuration file in /etc like for other plugins<br>CONFIG_FILE = &#39;/etc/koji-hub/plugins/sign.conf&#39;<br><br>def sign(cbtype, *args, **kws):<br>    if kws[&#39;type&#39;] != &#39;build&#39;:<br>       return<br>
<br>    # Get the tag name from the buildroot map<br>    import sys<br>    sys.path.insert(0, &#39;/usr/share/koji-hub&#39;)<br>    from kojihub import get_buildroot<br>    br_id = kws[&#39;brmap&#39;].values()[0]<br>    br = get_buildroot(br_id)<br>
    tag_name = br[&#39;tag_name&#39;]<br><br>    # Get GPG info using the config for the tag name<br>    import ConfigParser<br>    config = ConfigParser.ConfigParser()<br>    config.read(CONFIG_FILE)<br>    try:<br>        rpm = config.get(tag_name, &#39;rpm&#39;)<br>
    except ConfigParser.NoSectionError:<br>        rpm = config.get(ConfigParser.DEFAULTSECT, &#39;rpm&#39;)<br>    try:<br>        gpgbin = config.get(tag_name, &#39;gpgbin&#39;)<br>    except ConfigParser.NoSectionError:<br>
        gpgbin = config.get(ConfigParser.DEFAULTSECT, &#39;gpgbin&#39;)<br>    try:<br>        gpg_path = config.get(tag_name, &#39;gpg_path&#39;)<br>    except ConfigParser.NoSectionError:<br>        gpg_path = config.get(ConfigParser.DEFAULTSECT, &#39;gpg_path&#39;)<br>
    try:<br>        gpg_name = config.get(tag_name, &#39;gpg_name&#39;)<br>    except ConfigParser.NoSectionError:<br>        gpg_name = config.get(ConfigParser.DEFAULTSECT, &#39;gpg_name&#39;)<br>    try:<br>        gpg_pass = config.get(tag_name, &#39;gpg_pass&#39;)<br>
    except ConfigParser.NoSectionError:<br>        gpg_pass = config.get(ConfigParser.DEFAULTSECT, &#39;gpg_pass&#39;)<br><br>    # Get the package paths set up<br>    from koji import pathinfo<br>    uploadpath = pathinfo.work()<br>
    rpms = &#39;&#39;<br>    for relpath in [kws[&#39;srpm&#39;]] + kws[&#39;rpms&#39;]:<br>       rpms += &#39;%s/%s &#39; % (uploadpath, relpath)<br><br>    # Get the packages signed<br>    import pexpect<br>    import os<br>
    os.environ[&#39;LC_ALL&#39;] = &#39;C&#39;<br>    logging.getLogger(&#39;koji.plugin.sign&#39;).info(&#39;Attempting to sign packages&#39;<br>       &#39; (%s) with key &quot;%s&quot;&#39; % (rpms, gpg_name))<br>    rpm_cmd = &quot;%s --resign --define &#39;_signature gpg&#39;&quot; % rpm<br>
    rpm_cmd += &quot; --define &#39;_gpgbin %s&#39;&quot; % gpgbin<br>    rpm_cmd += &quot; --define &#39;_gpg_path %s&#39;&quot; % gpg_path<br>    rpm_cmd += &quot; --define &#39;_gpg_name %s&#39; %s&quot; % (gpg_name, rpms)<br>
    pex = pexpect.spawn(rpm_cmd, timeout=1000)<br>    # Add rpm output to a temporary file<br>    fout = os.tmpfile()<br>    pex.logfile = fout<br>    pex.expect(&#39;(E|e)nter (P|p)ass (P|p)hrase:&#39;, timeout=1000)<br>
    if not gpg_pass:<br>        pex.sendline(&#39;\r&#39;)<br>    else:<br>        pex.sendline(gpg_pass)<br>    i = pex.expect([&#39;good&#39;, &#39;failed&#39;, &#39;skipping&#39;, pexpect.TIMEOUT])<br>    pex.expect(pexpect.EOF)<br>
    if i == 0:<br>        logging.getLogger(&#39;koji.plugin.sign&#39;).info(&#39;Package sign successful!&#39;)<br>    elif i == 1:<br>        logging.getLogger(&#39;koji.plugin.sign&#39;).error(&#39;Pass phrase check failed!&#39;)<br>
    elif i == 2:<br>        logging.getLogger(&#39;koji.plugin.sign&#39;).error(&#39;Package sign skipped!&#39;)<br>    elif i == 3:<br>        logging.getLogger(&#39;koji.plugin.sign&#39;).error(&#39;Package sign timed out!&#39;)<br>
    else:<br>        logging.getLogger(&#39;koji.plugin.sign&#39;).error(&#39;Unexpected sign result!&#39;)<br>    if i != 0:<br>        # Rewind in rpm output<br>        fout.seek(0)<br>        # Add GPG errors to log<br>
        for line in fout.readlines():<br>            if &#39;gpg:&#39; in line:<br>                logging.getLogger(&#39;koji.plugin.sign&#39;).error(line.rstrip(&#39;\n&#39;))<br>        fout.close()<br>        raise Exception, &#39;Package sign failed!&#39;<br>
    else:<br>        fout.close()<br><br>register_callback(&#39;preImport&#39;, sign)<br><br><br><br><br><br>Regards,<br>Pierre<br><br><br>