Distribute Python modules using RPM

The Python Package Index (PyPI) website offers plenty of Python module source codes. To install these modules, it is needed to download and extract the archive and execute an installation script afterwards. Using the pip (pip installs packages) package manager, this process can be automated – e.g. for the nagiosplugin module:

# pip install nagiosplugin

If you are maintaing bigger system landscapes, this might not be an adequate option as it is hard to monitor and control installed modules using central software and patch management solutions. It would be great to distribute modules using RPM. Fortunately, the most Python modules come with installation scripts that offer pre-build routines for this.

The following example creates a RPM file for the module just mentioned:

$ wget https://pypi.python.org/packages/source/n/nagiosplugin/nagiosplugin-1.2.4.tar.gz
$ tar xf nagiosplugin-1.2.4.tar.gz ; cd nagiosplugin-1.2.4
$ python setup.py bdist_rpm
running bdist_rpm
running egg_info
moving build/bdist.linux-x86_64/rpm/SRPMS/nagiosplugin-1.2.4-1.src.rpm -> dist
moving build/bdist.linux.x86_64/rpm/RPMS/noarch/nagiosplugin-1.2.4-1.noarch.rpm -> dist

The python command needs to be executed in the folder, the source code was extracted. Try the following command if creating the RPM package fails (option/parameter incorrect):

$ python setup.py bdist --formats=rpm

Afterwards, the dist folder lists the appropriate RPM files (source code and installable package) and the module source code as well. The build directory contains various development files and the RPM sepcification. To give you some inspiration, this conventional specification can be used for Continuous Integration to create packages for multiple architectures and distributions. 🙂

If you only want to create the RPM specification without creating a RPM file, use the following command:

$ python setup.py bdist_rpm --spec-only

On Linux distributions, the process might crash with the following error:

UnicodeDecodeError: 'ascii' codec can't decode byte ... in position ...: ordinal not in range(128)

Usually, this issue is forced by non-Unicode characters in the module documentation. When creating the RPM specification, the Python installation script crashes (shouldn’t errors like this be catched at all?!). A possible solution is to search and replace/remove those characters with grep:

$ grep -P "[x80-xFF]" *.txt
CONTRIBUTORS.txt:* Simónè Gíèrtz

Sharing is caring

Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedInShare on XingShare on RedditPrint this pageEmail this to someone

Leave a Reply