I use/mirror a number of third-party Yum repositories. The typical pattern for these is to import the vendor’s public signing key using rpm --import and then setup a new entry /etc/yum.repos.d entry. Some vendors have -release packages that handle both steps. The trouble is, this creates a bit of a chicken/egg problem and doesn’t lend itself so well to automation.
Instead I tend to favour having Puppet manage the keys and repositories. Since the GPG keys don’t change very often we can safely import them into Puppet. Puppet pushes out the key as a file resource before setting up a Yum repository resource with the attribute gpgkey = file:///.
Here is what the resulting class for Jenkins looks like.
This pattern works fine for most vendors. It works fine for Jenkins on EL6. But it throws the following error on EL5.
Running yum install jenkins by hand results in exactly the same error. So we know it’s not Puppet getting in the way. Following the jenkins-ci.org instructions of running rpm --import and setting up the repository without gpgkey also works. So what’s the difference?
The best place to start would be the code in the traceback. Looking at __init__.py:getKeyForPackage() we can see that if Yum is given a gpgkey attribute it will make sure that the key is imported. It determines the presence and some other information about the key by calling misc.py:getpgpkeyinfo() which in turn uses pgpmsg.py to do the actual parsing. At the top of that file is a list of numeric packet types as constants.
For Yum 3.2.22, which is used in EL5, these numerics only go as high as 14. Which would explain why it’s complaining that 17 is unknown. By running git blame and git describe against Yum’s git repository we can see that the additional packet types were first present in Yum 3.2.25. Which explains why we don’t see the same problem in EL6 which uses Yum 3.2.29.
So what is packet type 17? The IANA assignments for PGP Packet Types/Tags tell us that it is a “User Attribute Packet”. The assignments for PGP User Attribute Types also tell us that there’s only one registered type of user attribute, suggesting that it must be an image.
It seems that an image shouldn’t be essential to our use of verifying package integrity. The good news is that we can remove it from the public key.
Start by obtaining a copy of the original public key.
Import it into GPG. The version of GPG that you use shouldn’t matter too much. I’m using a more recent version on my Mint desktop machine.
List the available keys to determine it’s identity. We’re after that hex value D50582E6.
Begin editing that key. We can see that there are three IDs within the key, the last one being the image that we want to remove. Mark it, delete it, and save the modifications.
Export the modifications to a new ASCII key file. We’ll give it a different filename to the original.
Now we can send out the modified key to any EL5 nodes and use the original for everyone else. Voila, the Puppet run completes and the package is installed successfully.
If you’re wondering, operatingsystemmajrelease is a custom fact. It works much like lsbmajdistrelease without the gazillion dependencies.