De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Ivan de Gusmão Apolonio
Data de Publicação: 04 de janeiro de 2010
Há muito tempo eu procurava um jeito simples de gerar um pacote RPM, mas simplesmente todos os tutoriais que eu encontrava na internet somente explicavam como se compilar um aplicativo e gerar um pacote RPM com o aplicativo compilado.
O que eu queria era algo muito mais simples: só queria fazer um pacote contendo um script que eu mesmo fiz ou uma árvore de diretórios com um conteúdo qualquer. Nas distribuições baseadas em Debian é fácil, pois a forma de se criar um pacote DEB é montar uma árvore de diretórios e gerar um pacote com o conteúdo da árvore.
Foi aí então que encontrei um projeto chamado dir2rpm, cuja finalidade é simplesmente esta: gerar um pacote RPM a partir de uma árvore de diretórios especificada. Baixei o script do site mas infelizmente dava uma série de erros e não funcionava (pelo menos na minha distribuição: CentOS 5.4). Fiz algumas alterações e agora está funcionando lindamente!! Gostaria de compartilhar aqui a versão modificada do script, sem tirar os créditos do criador Mildred Ki'Lya.
Apesar de sua utilização ser extremamente simples, vou dar um exemplo para facilitar o entendimento:
Suponhamos que eu queira criar um pacote RPM chamado meupacote, cujo
conteúdo é apenas um script chamado meuscript.sh o qual será instalado
no diretório /usr/local/bin. Vamos aos passos:
raiz, que será a raiz do meu pacote, e dentro dele crio a
estrutura de diretórios necessária.
mkdir -p raiz/usr/local/bin
meuscript.sh para para dentro do diretório
recém criado:
cp meuscript.sh raiz/usr/local/bin
dir2rpm.sh raiz meupacote-1.0
Por fim será criado o arquivo meupacote-1.0-1.x86_64.rpm (pois minha
plataforma é de 64bits).
OBS: o rpmbuild usa esquema para detectar automaticamente
as dependêcias que os pacotes possuem. Infelizmente em alguns casos
(especialmente os scripts em Perl), ele coloca como dependência um monte
de coisa que não existe e termina não criando o pacote. Para resolver este
problema eu tive que adicionar no código a opção "AutoReqProv: no"
para desativar a detecção de dependências para pacote que ele irá gerar.
Segue o código do script:
#! /bin/bash
## Copyright (c) 2009 Mildred Ki'Lya < mildred593(at)online.fr>
##
## Permission is hereby granted, free of charge, to any person
## obtaining a copy of this software and associated documentation
## files (the "Software"), to deal in the Software without
## restriction, including without limitation the rights to use,
## copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the
## Software is furnished to do so, subject to the following
## conditions:
##
## The above copyright notice and this permission notice shall be
## included in all copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
## OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
## HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
## OTHER DEALINGS IN THE SOFTWARE.
#**********************************************************************
#
# Additional modifications were made by Ivan de Gusmão Apolonio
#
#**********************************************************************
op_help=false
op_run=true
op_name=
while true; do
case "$1" in
--help)
op_help=true
op_run=false
;;
--name)
shift
op_name="$1"
;;
--) shift; break ;;
--*) echo "`basename "$0"`: unknown option $1" >&2; exit 1 ;;
-*)
opts="${1[2,-1]}"
while [[ 0 -lt "${#opts}" ]]; do
case "${opts[1]}" in
h) op_help=true ; op_run=false ;;
n) shift ; op_name="$1" ;;
*) echo "`basename "$0"`: unknown option -${opts[1]}" >&2; exit 1 ;;
esac
opts="${opts[2,-1]}"
done
;;
*) break ;;
esac
shift
done
op_dir="$1"
op_pkgname="$2"
name_ver_rel=$op_pkgname
if [[ -z "$name_ver_rel" ]]; then
name_ver_rel=$op_dir
fi
#
# Look at the release number: [0-9]*
#
rel=${name_ver_rel##*-}
if [[ -z "${rel//[0-9]/}" ]]; then
# rel is valid or empty
[[ -z "$rel" ]] && rel=1
name_ver=${name_ver_rel%-*}
valid_rel=true
else
rel=1
name_ver=$name_ver_rel
valid_rel=false
fi
#
# Look at the version number: [0-9\.]*
#
ver=${name_ver##*-}
if [[ -z "${ver//[0-9.]/}" ]]; then
# ver is valid or empty
[[ -z "$ver" ]] && ver=1.0
name=${name_ver%-*}
elif $valid_rel; then
# we mistook the version number for the release number
ver=$rel
rel=1
else
ver=1.0
name=$name_ver
fi
echo $name - $ver - $rel
if $op_help; then
echo "SYNOPSYS"
echo
echo " `basename "$0"` [OPTIONS] DIR [PKGNAME]"
echo
echo
echo "DESCRIPTION"
echo
echo " Create a RPM file based on the files in DIR"
echo
echo
echo "OPTIONS"
echo
echo " -h, --help"
echo
echo " -n, --name NAME"
echo
exit 0
fi
if ! $op_run; then
exit 0
fi
if [ -z "$op_name" ]; then
op_name=$op_dir
fi
rootdir=`pwd`/$op_dir
specfile=$op_dir.spec
rcfile=$op_dir.rc
all_files=$(find $op_dir -not -type d | cut -c$((${#op_dir}+1))-)
all_dirs=$(find $op_dir -type d | sed -e "s/$op_dir/%dir /" | sed 1d)
cat >$rcfile << EOF
EOF
cat >$specfile << EOF
%define _topdir $rootdir.rpmbuild
Summary: Autogenerated $name package
Name: $name
Version: $ver
Release: $rel
Group: Tools
License: Unknown
BuildRoot: $rootdir
AutoReqProv: no
%description
%define _topdir $rootdir.rpmbuild
%prep
%define _topdir $rootdir.rpmbuild
%build
%define _topdir $rootdir.rpmbuild
%install
%define _topdir $rootdir.rpmbuild
echo BEGIN INSTALL
if [ a'$rootdir' != a"\$RPM_BUILD_ROOT" ]; then
rmdir "\$RPM_BUILD_ROOT"
#ln -s '$rootdir' "\$RPM_BUILD_ROOT"
cp --archive '$rootdir' "\$RPM_BUILD_ROOT"
fi
echo END INSTALL
%clean
%define _topdir $rootdir.rpmbuild
if [ a'$rootdir' != a"\$RPM_BUILD_ROOT" ]; then
rm -rf "\$RPM_BUILD_ROOT"
fi
%files
%define _topdir $rootdir.rpmbuild
$all_dirs
$all_files
EOF
mkdir -p $rootdir.rpmbuild/{,BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
echo rpmbuild -bb --define "'_topdir $rootdir.rpmbuild'" $specfile
rpmbuild -bb --define "_topdir $rootdir.rpmbuild" $specfile
echo "Status: $?"
echo
while read rpm; do
cp $rpm `basename $rpm`
echo "Created `basename $rpm`"
done <<<$(find $rootdir.rpmbuild/RPMS -type f -name "*.rpm")
rm -rf $specfile $rcfile $rootdir.rpmbuild
exit 0