GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo construir paquetes rpm

He usado administradores de paquetes basados ​​en rpm para instalar software en Red Hat y Fedora Linux desde que comencé a usar Linux hace más de 20 años. He usado las rpm programa en sí, yum y DNF , que es un descendiente cercano de yum, para instalar y actualizar paquetes en mis hosts Linux. Las herramientas yum y DNF son contenedores de la utilidad rpm que brindan funcionalidad adicional, como la capacidad de encontrar e instalar dependencias de paquetes.

Más recursos de Linux

  • Hoja de trucos de los comandos de Linux
  • Hoja de trucos de comandos avanzados de Linux
  • Curso en línea gratuito:Descripción general técnica de RHEL
  • Hoja de trucos de red de Linux
  • Hoja de trucos de SELinux
  • Hoja de trucos de los comandos comunes de Linux
  • ¿Qué son los contenedores de Linux?
  • Nuestros últimos artículos sobre Linux

A lo largo de los años, he creado varios scripts de Bash, algunos de los cuales tienen archivos de configuración independientes, que me gusta instalar en la mayoría de mis nuevos equipos y máquinas virtuales. Llegó al punto en que tomó mucho tiempo instalar todos estos paquetes, así que decidí automatizar ese proceso creando un paquete rpm que pudiera copiar a los hosts de destino e instalar todos estos archivos en sus ubicaciones adecuadas. Aunque las rpm La herramienta se usaba anteriormente para crear paquetes rpm, esa función se eliminó y una nueva herramienta, rpmbuild, fue creado para construir nuevos rpms.

Cuando comencé este proyecto, encontré muy poca información sobre la creación de paquetes rpm, pero logré encontrar un libro, Maximum RPM , eso me ayudó a resolverlo. Ese libro ahora está algo desactualizado, al igual que la gran mayoría de la información que he encontrado. También está agotado y las copias usadas cuestan cientos de dólares. La versión en línea de Maximum RPM está disponible sin cargo y se mantiene actualizada. El sitio web de RPM también tiene enlaces a otros sitios web que tienen mucha documentación sobre rpm. La otra información que hay tiende a ser breve y aparentemente asume que usted ya tiene mucho conocimiento sobre el proceso.

Además, cada uno de los documentos que encontré asume que el código debe compilarse a partir de fuentes como en un entorno de desarrollo. No soy un desarrollador. Soy un administrador de sistemas, y nosotros, los administradores de sistemas, tenemos diferentes necesidades porque no compilamos, o no deberíamos, código para usar en tareas administrativas; deberíamos usar scripts de shell. Por lo tanto, no tenemos código fuente en el sentido de que es algo que debe compilarse en ejecutables binarios. Lo que tenemos es una fuente que también es el ejecutable.

En su mayor parte, este proyecto debe realizarse como estudiante usuario no root. Rpms nunca debe ser construido por root, sino solo por usuarios sin privilegios. Indicaré qué partes deben ser realizadas como root y cuáles por un usuario no root y sin privilegios.

Preparación

Primero, abra una sesión de terminal y su a raíz. Asegúrese de usar el - opción para asegurarse de que el entorno raíz completo esté habilitado. No creo que los administradores de sistemas deban usar sudo para cualquier tarea administrativa. Descubra por qué en mi entrada de blog personal:Los administradores de sistemas reales no hacen sudo .

[student@testvm1 ~]$ su -
Password:
[root@testvm1 ~]#

Cree un usuario estudiante que pueda usarse para este proyecto y establezca una contraseña para ese usuario.

[root@testvm1 ~]# useradd -c "Student User" student 
[root@testvm1 ~]# passwd student
Changing password for user student.
New password: <Enter the password>
Retype new password: <Enter the password>
passwd: all authentication tokens updated successfully.
[root@testvm1 ~]#

La creación de paquetes rpm requiere rpm-build paquete, que probablemente no esté ya instalado. Instálalo ahora como root. Tenga en cuenta que este comando también instalará varias dependencias. El número puede variar, según los paquetes ya instalados en su host; instaló un total de 17 paquetes en mi VM de prueba, que es bastante mínimo.

dnf install -y rpm-build

El resto de este proyecto debe realizarse como estudiante usuario, a menos que se indique explícitamente lo contrario. Abra otra sesión de terminal y use su para cambiar a ese usuario para realizar el resto de estos pasos. Descarga un tarball que he preparado de una estructura de directorios de desarrollo, utils.tar, desde GitHub usando el siguiente comando:

wget https://github.com/opensourceway/how-to-rpm/raw/master/utils.tar

Este tarball incluye todos los archivos y scripts de Bash que serán instalados por el rpm final. También hay un archivo de especificaciones completo, que puede usar para construir el rpm. Entraremos en detalles sobre cada sección del archivo de especificaciones.

Como estudiante usuario, utilizando su directorio de inicio como su directorio de trabajo actual (pwd), descomprima el tarball.

[student@testvm1 ~]$ cd ; tar -xvf utils.tar 

Usa el tree Comando para verificar que la estructura de directorios de ~/desarrollo y los archivos contenidos se parece al siguiente resultado:

[student@testvm1 ~]$ tree development/
development/
├── license
│   ├── Copyright.and.GPL.Notice.txt
│   └── GPL_LICENSE.txt
├── scripts
│   ├── create_motd
│   ├── die
│   ├── mymotd
│   └── sysdata
└── spec
    └── utils.spec

3 directories, 7 files
[student@testvm1 ~]$

El mymotd script crea un flujo de datos de "Mensaje del día" que se envía a stdout. El create_motd script ejecuta el mymotd scripts y redirige la salida al archivo /etc/motd. Este archivo se utiliza para mostrar un mensaje diario a los usuarios que inician sesión de forma remota mediante SSH.

El die script es mi propio script que envuelve el kill Comando en un fragmento de código que puede encontrar programas en ejecución que coincidan con una cadena específica y eliminarlos. Utiliza kill -9 para asegurarse de que no puedan ignorar el mensaje de muerte.

Los sysdata El script puede arrojar decenas de miles de líneas de datos sobre el hardware de su computadora, la versión instalada de Linux, todos los paquetes instalados y los metadatos de sus discos duros. Lo uso para documentar el estado de un host en un momento dado. Más tarde puedo usarlo como referencia. Solía ​​hacer esto para mantener un registro de los hosts que instalaba para los clientes.

Es posible que deba cambiar la propiedad de estos archivos y directorios a estudiante.estudiante. Haga esto, si es necesario, usando el siguiente comando:

chown -R student.student development

La mayoría de los archivos y directorios de este árbol se instalarán en los sistemas Fedora mediante el rpm que cree durante este proyecto.

Crear la estructura del directorio de construcción

El rpmbuild El comando requiere una estructura de directorios muy específica. Debe crear esta estructura de directorios usted mismo porque no se proporciona ninguna forma automatizada. Cree la siguiente estructura de directorios en su directorio de inicio:

~ ─ rpmbuild
    ├── RPMS
    │   └── noarch
    ├── SOURCES
    ├── SPECS
    └── SRPMS

No crearemos el directorio rpmbuild/RPMS/X86_64 porque sería específico de la arquitectura para binarios compilados de 64 bits. Tenemos scripts de shell que no son específicos de la arquitectura. En realidad, tampoco usaremos el directorio SRPMS, que contendría archivos fuente para el compilador.

Examinando el archivo de especificaciones

Cada archivo de especificaciones tiene varias secciones, algunas de las cuales pueden ignorarse u omitirse, según las circunstancias específicas de la compilación de rpm. Este archivo de especificaciones en particular no es un ejemplo de un archivo mínimo requerido para funcionar, pero es un buen ejemplo de un archivo de especificaciones moderadamente complejo que empaqueta archivos que no necesitan ser compilados. Si se requiriera una compilación, se realizaría en el %build sección, que se omite en este archivo de especificaciones porque no es necesaria.

Preámbulo

Esta es la única sección del archivo de especificaciones que no tiene una etiqueta. Consiste en gran parte de la información que ve cuando el comando rpm -qi [Package Name] se ejecuta Cada dato es una sola línea que consta de una etiqueta, que lo identifica y datos de texto para el valor de la etiqueta.

###############################################################################
# Spec file for utils
################################################################################
# Configured to be built by user student or other non-root user
################################################################################
#
Summary: Utility scripts for testing RPM creation
Name: utils
Version: 1.0.0
Release: 1
License: GPL
URL: http://www.both.org
Group: System
Packager: David Both
Requires: bash
Requires: screen
Requires: mc
Requires: dmidecode
BuildRoot: ~/rpmbuild/

# Build with the following syntax:
# rpmbuild --target noarch -bb utils.spec

Las líneas de comentario son ignoradas por rpmbuild programa. Siempre me gusta agregar un comentario a esta sección que contiene la sintaxis exacta del rpmbuild comando necesario para crear el paquete. La etiqueta Resumen es una breve descripción del paquete. Las etiquetas Nombre, Versión y Versión se utilizan para crear el nombre del archivo rpm, como en utils-1.00-1.rpm. Incrementar los números de lanzamiento y versión le permite crear RPM que se pueden usar para actualizar los más antiguos.

La etiqueta de licencia define la licencia bajo la cual se publica el paquete. Siempre uso una variación de la GPL. Es importante especificar la licencia para aclarar el hecho de que el software contenido en el paquete es de código abierto. Esta es también la razón por la que incluí la licencia y la declaración GPL en los archivos que se instalarán.

La URL suele ser la página web del proyecto o del propietario del proyecto. En este caso, es mi página web personal.

La etiqueta de grupo es interesante y generalmente se usa para aplicaciones GUI. El valor de la etiqueta de grupo determina qué grupo de íconos en el menú de aplicaciones contendrá el ícono para el ejecutable en este paquete. Usada junto con la etiqueta de icono (que no estamos usando aquí), la etiqueta de grupo permite agregar el icono y la información necesaria para iniciar un programa en la estructura del menú de aplicaciones.

La etiqueta Packager se usa para especificar la persona u organización responsable de mantener y crear el paquete.

Las instrucciones Requires definen las dependencias para este rpm. Cada uno es un nombre de paquete. Si uno de los paquetes especificados no está presente, la utilidad de instalación de DNF intentará ubicarlo en uno de los repositorios definidos en /etc/yum.repos.d e instalarlo si existe. Si DNF no puede encontrar uno o más de los paquetes requeridos, arrojará un error que indica qué paquetes faltan y terminará.

La línea BuildRoot especifica el directorio de nivel superior en el que rpmbuild tool encontrará el archivo de especificaciones y en el que creará directorios temporales mientras construye el paquete. El paquete terminado se almacenará en el subdirectorio noarch que especificamos anteriormente. El comentario que muestra la sintaxis del comando utilizado para crear este paquete incluye la opción –target noarch , que define la arquitectura de destino. Debido a que estos son scripts de Bash, no están asociados con una arquitectura de CPU específica. Si se omitiera esta opción, la compilación estaría dirigida a la arquitectura de la CPU en la que se realiza la compilación.

El rpmbuild El programa puede apuntar a muchas arquitecturas diferentes, y usando el --target La opción nos permite construir paquetes específicos de arquitectura en un host con una arquitectura diferente de aquella en la que se realiza la construcción. Por lo tanto, podría crear un paquete diseñado para usarse en una arquitectura i686 en un host x86_64 y viceversa.

Cambie el nombre del empaquetador al suyo y la URL a su propio sitio web, si tiene uno.

%descripción

El %description La sección del archivo de especificaciones contiene una descripción del paquete rpm. Puede ser muy corto o puede contener muchas líneas de información. Nuestro %description la sección es bastante concisa.

%description
A collection of utility scripts for testing RPM creation.

% preparación

El %prep La sección es el primer script que se ejecuta durante el proceso de compilación. Este script no se ejecuta durante la instalación del paquete.

Este script es solo un script de shell Bash. Prepara el directorio de compilación, creando directorios utilizados para la compilación según sea necesario y copiando los archivos apropiados en sus respectivos directorios. Esto incluiría las fuentes requeridas para una compilación completa como parte de la compilación.

El directorio $RPM_BUILD_ROOT representa el directorio raíz de un sistema instalado. Los directorios creados en el directorio $RPM_BUILD_ROOT son rutas completas, como /user/local/share/utils, /usr/local/bin, etc., en un sistema de archivos en vivo.

En el caso de nuestro paquete, no tenemos fuentes precompiladas ya que todos nuestros programas son scripts Bash. Así que simplemente copiamos esos scripts y otros archivos en los directorios a los que pertenecen en el sistema instalado.

%prep
################################################################################
# Create the build tree and copy the files from the development directories    #
# into the build tree.                                                         #
################################################################################
echo "BUILDROOT = $RPM_BUILD_ROOT"
mkdir -p $RPM_BUILD_ROOT/usr/local/bin/
mkdir -p $RPM_BUILD_ROOT/usr/local/share/utils

cp /home/student/development/utils/scripts/* $RPM_BUILD_ROOT/usr/local/bin
cp /home/student/development/utils/license/* $RPM_BUILD_ROOT/usr/local/share/utils
cp /home/student/development/utils/spec/* $RPM_BUILD_ROOT/usr/local/share/utils

exit

Tenga en cuenta que se requiere la declaración de salida al final de esta sección.

%archivos

Esta sección del archivo de especificaciones define los archivos que se instalarán y sus ubicaciones en el árbol de directorios. También especifica los atributos del archivo y el propietario y el propietario del grupo para cada archivo que se instalará. Los permisos y las propiedades de los archivos son opcionales, pero recomiendo que se configuren explícitamente para eliminar cualquier posibilidad de que esos atributos sean incorrectos o ambiguos cuando se instalen. Los directorios se crean según sea necesario durante la instalación si aún no existen.

%files
%attr(0744, root, root) /usr/local/bin/*
%attr(0644, root, root) /usr/local/share/utils/*

% anterior

Esta sección está vacía en el archivo de especificaciones de nuestro proyecto de laboratorio. Este sería el lugar para colocar cualquier secuencia de comandos que se requiera ejecutar durante la instalación de rpm pero antes de la instalación de los archivos.

% publicación

Esta sección del archivo de especificaciones es otro script de Bash. Este se ejecuta después de la instalación de archivos. Esta sección puede ser prácticamente cualquier cosa que necesite o quiera que sea, incluida la creación de archivos, la ejecución de comandos del sistema y el reinicio de servicios para reiniciarlos después de realizar cambios en la configuración. El %post El script para nuestro paquete rpm realiza algunas de esas tareas.

%post
################################################################################
# Set up MOTD scripts                                                          #
################################################################################
cd /etc
# Save the old MOTD if it exists
if [ -e motd ]
then
   cp motd motd.orig
fi
# If not there already, Add link to create_motd to cron.daily
cd /etc/cron.daily
if [ ! -e create_motd ]
then
   ln -s /usr/local/bin/create_motd
fi
# create the MOTD for the first time
/usr/local/bin/mymotd > /etc/motd

Los comentarios incluidos en este script deben dejar claro su propósito.

% postun

Esta sección contiene un script que se ejecutará después de desinstalar el paquete rpm. El uso de rpm o DNF para eliminar un paquete elimina todos los archivos enumerados en %files sección, pero no elimina archivos o enlaces creados por %post sección, por lo que debemos manejar eso en esta sección.

Este script generalmente consiste en tareas de limpieza que simplemente borrar los archivos previamente instalados por el rpm no se pueden realizar. En el caso de nuestro paquete, incluye eliminar el enlace creado por el %post script y restaurar el original guardado del archivo motd.

%postun
# remove installed files and links
rm /etc/cron.daily/create_motd

# Restore the original MOTD if it was backed up
if [ -e /etc/motd.orig ]
then
   mv -f /etc/motd.orig /etc/motd
fi

% limpio

Este script de Bash realiza la limpieza después del proceso de compilación de rpm. Las dos líneas en %clean La siguiente sección elimina los directorios de compilación creados por rpm-build dominio. En muchos casos, también puede ser necesaria una limpieza adicional.

%clean
rm -rf $RPM_BUILD_ROOT/usr/local/bin
rm -rf $RPM_BUILD_ROOT/usr/local/share/utils

%registro de cambios

Esta sección de texto opcional contiene una lista de cambios en el rpm y los archivos que contiene. Los cambios más recientes se registran en la parte superior de esta sección.

%changelog
* Wed Aug 29 2018 Your Name <[email protected]>
  - The original package includes several useful scripts. it is
    primarily intended to be used to illustrate the process of
    building an RPM.

Reemplace los datos en la línea de encabezado con su propio nombre y dirección de correo electrónico.

Construyendo las rpm

El archivo de especificaciones debe estar en el directorio SPECS del árbol rpmbuild. Me resulta más fácil crear un enlace al archivo de especificaciones real en ese directorio para que pueda editarse en el directorio de desarrollo y no haya necesidad de copiarlo en el directorio SPECS. Haga que el directorio SPECS sea su pwd, luego cree el enlace.

cd ~/rpmbuild/SPECS/
ln -s ~/development/spec/utils.spec

Ejecute el siguiente comando para generar rpm. Solo debería llevar un momento crear las rpm si no se producen errores.

rpmbuild --target noarch -bb utils.spec

Compruebe en el directorio ~/rpmbuild/RPMS/noarch para verificar que el nuevo rpm existe allí.

[student@testvm1 ~]$ cd rpmbuild/RPMS/noarch/
[student@testvm1 noarch]$ ll
total 24
-rw-rw-r--. 1 student student 24364 Aug 30 10:00 utils-1.0.0-1.noarch.rpm
[student@testvm1 noarch]$

Probando las rpm

Como root, instale el rpm para verificar que se instala correctamente y que los archivos están instalados en los directorios correctos. El nombre exacto de rpm dependerá de los valores que haya usado para las etiquetas en la sección Preámbulo, pero si usó los del ejemplo, el nombre de rpm será como se muestra en el siguiente comando de ejemplo:

[root@testvm1 ~]# cd /home/student/rpmbuild/RPMS/noarch/
[root@testvm1 noarch]# ll
total 24
-rw-rw-r--. 1 student student 24364 Aug 30 10:00 utils-1.0.0-1.noarch.rpm
[root@testvm1 noarch]# rpm -ivh utils-1.0.0-1.noarch.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:utils-1.0.0-1                    ################################# [100%]

Verifique /usr/local/bin para asegurarse de que los nuevos archivos estén allí. También debe verificar que se haya creado el enlace create_motd en /etc/cron.daily.

Usa las rpm -q --changelog utils comando para ver el registro de cambios. Ver los archivos instalados por el paquete usando rpm -ql utils comando (que es una L minúscula en ql .)

[root@testvm1 noarch]# rpm -q --changelog utils
* Wed Aug 29 2018 Your Name <[email protected]>
- The original package includes several useful scripts. it is
    primarily intended to be used to illustrate the process of
    building an RPM.

[root@testvm1 noarch]# rpm -ql utils
/usr/local/bin/create_motd
/usr/local/bin/die
/usr/local/bin/mymotd
/usr/local/bin/sysdata
/usr/local/share/utils/Copyright.and.GPL.Notice.txt
/usr/local/share/utils/GPL_LICENSE.txt
/usr/local/share/utils/utils.spec
[root@testvm1 noarch]#

Retire el paquete.

rpm -e utils

Experimentando

Ahora cambiará el archivo de especificaciones para requerir un paquete que no existe. Esto simulará una dependencia que no se puede cumplir. Agregue la siguiente línea inmediatamente debajo de la línea Requiere existente:

Requires: badrequire

Genere el paquete e intente instalarlo. ¿Qué mensaje se muestra?

Usamos el rpm comando para instalar y eliminar utils paquete. Intente instalar el paquete con yum o DNF. Debe estar en el mismo directorio que el paquete o especificar la ruta completa al paquete para que esto funcione.

Conclusión

Hay muchas etiquetas y un par de secciones que no cubrimos en este vistazo a los aspectos básicos de la creación de un paquete rpm. Los recursos enumerados a continuación pueden proporcionar más información. Construir paquetes rpm no es difícil; solo necesitas la información correcta. Espero que esto te ayude, me tomó meses resolver las cosas por mi cuenta.

No cubrimos la creación a partir del código fuente, pero si eres un desarrollador, ese debería ser un paso simple desde este punto.

Crear paquetes rpm es otra buena manera de ser un administrador de sistemas perezoso y ahorrar tiempo y esfuerzo. Proporciona un método fácil para distribuir e instalar los scripts y otros archivos que nosotros, como administradores de sistemas, necesitamos instalar en muchos hosts.

Recursos

  • Edward C. Baily, RPM máximas , Sams Publishing, 2000, ISBN 0-672-31105-4

  • Edward C. Baily, RPM máximas , versión en línea actualizada

  • Documentación RPM :Esta página web enumera la mayor parte de la documentación en línea disponible para rpm. Incluye muchos enlaces a otros sitios web e información sobre rpm.


Linux
  1. Cómo usar el comando apt para administrar paquetes en Linux

  2. Cómo crear un paquete RPM de Linux

  3. Cómo enumerar todos los paquetes instalados en Linux

  4. Cómo instalar paquetes RPM en Ubuntu

  5. Cómo verificar el proveedor de paquetes RPM instalados en Linux

Cómo instalar paquetes .tar.gz o .tgz en Linux

Cómo instalar Anaconda en Linux

Cómo convertir paquetes de Linux con Alien

Cómo enumerar los paquetes instalados en Linux

Cómo construir el kernel de Linux desde cero

Cómo usar el comando RPM en Linux