Pesquisa de site

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.

Artigos relacionados: