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