unRPM

Apesar de adorar Debian e Ubuntu, o trabalho me exige mexer com pacotes RPM.  Ao contrário do format DEB, os pacotes RPM são mais simples de gerar.  Basta ter um arquivo SPEC, que informa os dados dos pacote como dependência e scripts para instalação, que é possível gerar usando rpmbuild.  Mesmo num Debian/Ubuntu.

Mas cai no caso de uma aplicação de opensaf já compilada.  E precisava gerar um pacote só com versão diferente, pra testar uma campanha de upgrade.  A solução seria desmontar o pacote RPM e montar novamente.  Um "unrpm" por assim dizer.  Eu tentei usar um pacote "rpmrebuild", mas o mesmo é feito pra sistemas já com uso de RPM, e precisa que o pacote esteja instalado pra conseguir reconstuir o mesmo.  Com certeza não o meu caso.

A parte do conteúdo não é difícil de fazer pois o pacote RPM é na verdade um arquivo de CPIO.  Usando como exemplo o pacote aalib-libs do fedora 20, com comandos rpm é possível ver as informações do pacote e seu conteúdo:

helio@debian:~$ rpm -qip aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm
warning: aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 246110c1: NOKEY
Name : aalib-libs
Version : 1.4.0
Release : 0.23.rc5.fc20
Architecture: x86_64
Install Date: (not installed)
Group : System/Libraries
Size : 159154
License : LGPLv2+
Signature : RSA/SHA256, Fri 16 Aug 2013 05:21:44 PM CEST, Key ID 2eb161fa246110c1
Source RPM : aalib-1.4.0-0.23.rc5.fc20.src.rpm
Build Date : Sat 03 Aug 2013 02:17:12 AM CEST
Build Host : buildvm-07.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager : Fedora Project
Vendor : Fedora Project
URL : http://aa-project.sourceforge.net/aalib/
Summary : Library files for aalib
Description :
This package contains library files for aalib.
helio@debian:~$ rpm -qlp aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm
warning: aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 246110c1: NOKEY
/usr/lib64/libaa.so.1
/usr/lib64/libaa.so.1.0.4
/usr/share/doc/aalib-libs
/usr/share/doc/aalib-libs/COPYING
/usr/share/doc/aalib-libs/ChangeLog
/usr/share/doc/aalib-libs/NEWS
/usr/share/doc/aalib-libs/README

Com o comando rpm2cpio seguido de cpio, é possível verificar que o conteúdo é o mesmo, sem perdas.

helio@debian:~$ cat aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm | rpm2cpio - | cpio -itv
lrwxrwxrwx 1 root root 14 Aug 3 2013 ./usr/lib64/libaa.so.1 -> libaa.so.1.0.4
-rwxr-xr-x 1 root root 125872 Aug 3 2013 ./usr/lib64/libaa.so.1.0.4
drwxr-xr-x 2 root root 0 Aug 3 2013 ./usr/share/doc/aalib-libs
-rw-r--r-- 1 root root 25265 Apr 26 2001 ./usr/share/doc/aalib-libs/COPYING
-rw-r--r-- 1 root root 3649 Apr 26 2001 ./usr/share/doc/aalib-libs/ChangeLog
-rw-r--r-- 1 root root 764 Apr 26 2001 ./usr/share/doc/aalib-libs/NEWS
-rw-r--r-- 1 root root 3604 Apr 26 2001 ./usr/share/doc/aalib-libs/README
314 blocks

Para extrair o conteúdo, bastaria usar as opções "-idv" do cpio.

Mas ainda falta os scripts de instalação que fazem a parte de pré-instalação, pós-instalação, pré-remoção e pós-remoção.  Como escolhi um pacote de biblioteca, esses não precisam de algo assim.  Pegando um pacote de servidor, no caso o bind - servidor de dns, é possível ver esses scripts que compões o SPEC.  Basta usar o comando "rpm --scripts -qp <pacote>".

helio@debian:~$ rpm --scripts -qp bind-9.9.4-8.fc20.x86_64.rpm
warning: bind-9.9.4-8.fc20.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 246110c1: NOKEY
preinstall scriptlet (using /bin/sh):
if [ "$1" -eq 1 ]; then
/usr/sbin/groupadd -g 25 -f -r named >/dev/null 2>&1 || :;
/usr/sbin/useradd -u 25 -r -N -M -g named -s /sbin/nologin -d /var/named -c Named named >/dev/null 2>&1 || :;
fi;
:;
postinstall scriptlet (using /bin/sh):
/sbin/ldconfig

if [ $1 -eq 1 ] ; then
# Initial installation
/usr/bin/systemctl preset named.service >/dev/null 2>&1 || :
fi
if [ "$1" -eq 1 ]; then
# Initial installation
[ -x /sbin/restorecon ] && /sbin/restorecon /etc/rndc.* /etc/named.* >/dev/null 2>&1 ;
# rndc.key has to have correct perms and ownership, CVE-2007-6283
[ -e /etc/rndc.key ] && chown root:named /etc/rndc.key
[ -e /etc/rndc.key ] && chmod 0640 /etc/rndc.key
fi
:;
preuninstall scriptlet (using /bin/sh):
# Package removal, not upgrade

if [ $1 -eq 0 ] ; then
# Package removal, not upgrade
/usr/bin/systemctl --no-reload disable named.service > /dev/null 2>&1 || :
/usr/bin/systemctl stop named.service > /dev/null 2>&1 || :
fi
postuninstall scriptlet (using /bin/sh):
/sbin/ldconfig
# Package upgrade, not uninstall

/usr/bin/systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ] ; then
# Package upgrade, not uninstall
/usr/bin/systemctl try-restart named.service >/dev/null 2>&1 || :
fi

Com essas informações é possível construir um pacote RPM binário.  Claro que no caso isso não é necessário pois bastaria pegar o pacote SRC e fazer o build novamente.  No meu caso, eu não sabia onde estavam os fontes e essa forma foi muito mais rápida, ainda mais que eu só precisava modificar a informação de versão pra testar upgrade.