Empacote um novo módulo Python em 4 etapas
O comando pyp2rpm permite criar um pacote RPM e automatizar o processo.
Ao instalar um aplicativo, geralmente você instala um pacote que contém o código executável de um aplicativo e arquivos importantes, como documentação, ícones e assim por diante. No Linux, os aplicativos são comumente empacotados como arquivos RPM ou DEB, e os usuários os instalam com os comandos dnf
ou apt
, dependendo da distribuição do Linux. No entanto, novos módulos Python são lançados praticamente todos os dias, então você pode facilmente encontrar um módulo que ainda não foi empacotado. E é exatamente por isso que existe o comando pyp2rpm
.
Recentemente, tentei instalar um módulo chamado python-concentration. Não correu bem:
$ sudo dnf install python-concentration
Updating Subscription Management repositories.
Last metadata expiration check: 1:23:32 ago on Sat 11 Jun 2022 06:37:25.
No match for argument: python-concentration
Error: Unable to find a match: python-concentration
É um pacote PyPi, mas ainda não está disponível como pacote RPM. A boa notícia é que você mesmo pode construir um RPM com um processo relativamente simples usando pyp2rpm
.
Você precisará de dois diretórios para começar:
$ mkdir rpmbuild
$ cd rpmbuild && mkdir SPECS
Você também precisará instalar o pyp2rpm
:
$ sudo dnf install pyp2rpm
1. Gere o arquivo de especificações
A base de qualquer pacote RPM é um arquivo chamado arquivo spec. Este arquivo contém todas as informações sobre como construir o pacote, quais dependências ele precisa, a versão do aplicativo que ele fornece, quais arquivos ele instala e muito mais. Quando apontado para um módulo Python, pyp2rpm
gera um arquivo de especificação para ele, que você pode usar para construir um RPM.
Usando python-concentration como exemplo arbitrário, veja como gerar um arquivo de especificações:
$ pyp2rpm concentration > ~/rpmbuild/SPECS/concentration.spec
E aqui está o arquivo que ele gera:
# Created by pyp2rpm-3.3.8
%global pypi_name concentration
%global pypi_version 1.1.5
Name: python-%{pypi_name}
Version: %{pypi_version}
Release: 1%{?dist}
Summary: Get work done when you need to, goof off when you don't
License: None
URL: None
Source0: %{pypi_source}
BuildArch: noarch
BuildRequires: python3-devel
BuildRequires: python3dist(setuptools)
%description
Concentration [![PyPI version]( [![Test Status]( [![Lint Status]( [![codecov](
%package -n python3-%{pypi_name}
Summary: %{summary}
%{?python_provide:%python_provide python3-%{pypi_name}}
Requires: (python3dist(hug) >= 2.6.1 with python3dist(hug) < 3~~)
Requires: python3dist(setuptools)
%description -n python3-%{pypi_name}
Concentration [![PyPI version]( [![Test Status]( [![Lint Status]( [![codecov](
%prep
%autosetup -n %{pypi_name}-%{pypi_version}
%build
%py3_build
%install
%py3_install
%files -n python3-%{pypi_name}
%license LICENSE
%doc README.md
%{_bindir}/concentration
%{python3_sitelib}/%{pypi_name}
%{python3_sitelib}/%{pypi_name}-%{pypi_version}-py%{python3_version}.egg-info
%changelog
* - 1.1.5-1
- Initial package.
2. Execute rpmlint
Para garantir que o arquivo de especificação esteja de acordo com os padrões, execute o comando rpmlint
no arquivo:
$ rpmlint ~/rpmbuild/SPEC/concentration.spec
error: bad date in %changelog: - 1.1.5-1
0 packages and 1 specfiles checked; 0 errors, 0 warnings.
Parece que a entrada do changelog requer uma data.
%changelog
* Sat Jun 11 2022 Tux <tux@example.com> - 1.1.5-1
Tente rpmlint
novamente:
$ rpmlint ~/rpmbuild/SPEC/concentration.spec
0 packages and 1 specfiles checked; 0 errors, 0 warnings.
Sucesso!
3. Baixe o código-fonte
Para construir um pacote RPM, você deve baixar o código que está empacotando. A maneira mais fácil de fazer isso é analisar seu arquivo de especificações para encontrar a localização do código-fonte na Internet.
Primeiro, instale o comando spectool
com dnf
:
$ sudo dnf install spectool
Em algumas distribuições, spectool
é distribuído no pacote rpmdevtools
.
Em seguida, use-o para baixar o código-fonte:
$ cd ~/rpmbuild
$ spectool -g -R SPEC/concentration.spec
Downloading: https://files.pythonhosted.org/...concentration-1.1.5.tar.gz
6.0 KiB / 6.0 KiB [=====================================]
Downloaded: concentration-1.1.5.tar.gz
Isso cria um diretório SOURCES e coloca o arquivo do código-fonte nele.
4. Construa o pacote fonte
Agora que você tem um arquivo de especificações válido, é hora de compilar o pacote fonte com o comando rpmbuild
. Se você ainda não tem o rpmbuild
, instale o pacote rpm-build com dnf
(ou aceite a oferta do seu terminal para instalar esse pacote quando você tentar usar o comando rpmbuild
).
$ cd ~/rpmbuild
$ spectool -g -R SPEC/concentration.spec
Downloading: https://files.pythonhosted.org/...concentration-1.1.5.tar.gz
6.0 KiB / 6.0 KiB [=====================================]
Downloaded: concentration-1.1.5.tar.gz
A opção -bs
significa build source. Esta opção fornece um arquivo src.rpm
, um pacote para todos os fins que deve ser reconstruído para uma arquitetura específica.
$ rpmbuild -bs SPECS/concentration.spec
Wrote: ~/rpmbuild/SRPMS/python-concentration-1.1.5-1.el9.src.rpm
Crie um RPM instalável para o seu sistema:
$ rpmbuild --rebuild SRPMS/python-concentration-1.1.5-1.el9.src.rpm
error: Failed build dependencies:
python3-devel is needed by python-concentration-1.1.5-1.el9.noarch
Parece que este pacote requer as bibliotecas de desenvolvimento do Python. Instale-os para continuar com a construção. Desta vez, a compilação foi bem-sucedida e renderizou muito mais resultados (que abrevio aqui para maior clareza):
$ sudo dnf install python3-devel -y
$ rpmbuild --rebuild SRPMS/python-concentration-1.1.5-1.el9.src.rpm
[...]
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.TYA7l2
+ umask 022
+ cd /home/bogus/rpmbuild/BUILD
+ rm -rf concentration-1.1.5
+ RPM_EC=0
++ jobs -p
+ exit 0
Seu pacote RPM foi criado no subdiretório RPMS. Instale-o normalmente com dnf
:
$ sudo dnf install RPMS/noarch/python3-concentration*rpm
Por que não usar apenas o PyPi?
Não é absolutamente necessário transformar um módulo Python em um RPM. Instalar um módulo com PyPi também é aceitável, mas o PyPi adiciona outro gerenciador de pacotes à sua lista pessoal de coisas para verificar e atualizar. Ao instalar um RPM usando dnf
, você terá uma lista completa do que instalou em seu sistema. Graças ao pyp2rpm
, o processo é rápido, fácil e automatizável.