sábado, 2 de enero de 2016

Cómo crear paquetes RPM

    Un día tuve que instalar una versión de un software para el cual no existía un .rpm para mi distribución (Fedora), pude encontrar el código fuente de la actualización pero no quería instalarlo siguiendo los clásicos ./configure, make y make install ya que si lo hacía así no iba a ser fácil desinstalarlo y volver a dejar mi sistema operativo como estaba.

    Y es que precisamente para eso están los manejadores de paquetes, con ellos no tenemos que preocuparnos por las dependencias de nuestros paquetes, ni tenemos que saber qué archivos el paquete instaló en nuestro equipo para después borrarlos, etc. Todo esto lo hace el manejador de paquetes automáticamente. El manejador de paquetes por lo general utiliza una base de datos que mantiene toda la información de los paquetes instalados, sus dependencias, etc.

    Cada vez que se necesita remover un paquete, por ejemplo, el manejador de paquetes sabe qué archivos este paquete instaló y los puede borrar. También sabe si este paquete depende de otros o si otros dependen de él.

    El tema de este artículo es cómo crear un paquete a partir del código fuente de un software que deseamos instalar para poder aprovechar las ventajas del manejador de paquetes de Red Hat (RPM), el mismo que se utiliza en Fedora, Centos y Suse.

    Lo primero que hice fue descargar una versión anterior del paquete con el código fuente del programa que deseaba actualizar. Para esto simplemente utilicé el siguiente comando:

dnf download --source telepathy-gabble-0.18.2

    Este comando habilita los repositorios que contienen el código fuente de los programas y descarga el paquete telepathy-gabble-0.18.2-5.fc23.src.rpm en el directorio en el que nos encontramos actualmente.

    En CentOS o Red Hat todavía se utiliza yum, por lo que el comando para descargar el paquete en esas distribuciones sería:

yum  download --source telepathy-gabble-0.18.2

    Los paquetes src.rpm son paquetes de código fuente y traen todo lo necesario para construir un paquete rpm con la aplicación compilada y toda la metadata, o sea que a partir de un src.rpm podemos construir un paquete rpm "normal" o un paquete que solamente contiene los binarios y toda la información necesaria para actualizar la base de datos del manejador de paquetes.

    Es por ello que al instalar un paquete src.rpm no se instala la aplicación propiamente, sino que al instalarlo éste genera una serie de directorios con el código fuente de la aplicación, los patches, y el .spec que es un archivo que rpmbuild utiliza para saber cómo contruir el paquete. O sea, todo lo necesario para crear un rpm.

    En Fedora para instalar el src.rpm se utilizan los mismos comandos que para instalar un paquete binario

rpm -i  telepathy-gabble-0.18.2-5.fc23.src.rpm

   Eso me crea un directorio en mi home llamado rpmbuild con los siguientes directorios:



    Es importante señalar que tanto para instalar el src.rpm como para construir el binario no hace falta ser root ya que estamos trabajando en el directorio del usuario normal y no estamos instalando la aplicación, simplemente estamos creando un nuevo rpm. También la localización y el nombre del directorio rpmbuild pueden variar en otras distribuciones.

    En esta captura de pantalla se puede observar que tengo varios paquetes tar.gz que contienen el código fuente de la aplicación, así como varios patches. Naturalmente la última versión del código fuente (0.18.3) la agregué yo para poder construir la nueva versión del rpm.  El código fuente lo bajé desde http://telepathy.freedesktop.org/releases/telepathy-gabble/telepathy-gabble-0.18.3.tar.gz

    Así las cosas, sólo quedaba modificar el correspondiente .spec con las instrucciones para compilar y construir el paquete rpm:

%if 0%{?rhel}
%global run_tests 0
%else
%global run_tests 1
%endif

Name:           telepathy-gabble
Version:        0.18.2
Release:        5%{?dist}
Summary:        A Jabber/XMPP connection manager

Group:          Applications/Communications
License:        LGPLv2+
URL:            http://telepathy.freedesktop.org/wiki/
Source0:        http://telepathy.freedesktop.org/releases/%{name}/%{name}-%{version}.tar.gz
Patch1:         telepathy-gabble-0.18.0-build.patch
Patch2:         0001-xmpp-console-Explicitly-state-python-in-the-shebang.patch

BuildRequires:  dbus-devel >= 1.1.0
BuildRequires:  dbus-glib-devel >= 0.82
BuildRequires:  telepathy-glib-devel >= 0.19.9
BuildRequires:  glib2-devel >= 2.32
BuildRequires:  gnutls-devel >= 2.12.0
BuildRequires:  sqlite-devel
BuildRequires:  libuuid-devel
BuildRequires:  libsoup-devel
BuildRequires:  libnice-devel >= 0.0.11
BuildRequires:  cyrus-sasl-devel
BuildRequires:  libxslt
%if %{run_tests}
# Build Requires needed for tests.
BuildRequires:  python
BuildRequires:  python-twisted
BuildRequires:  dbus-python
BuildRequires:  pygobject2
%endif

Requires:       telepathy-mission-control >= 5.5.0
Requires:       telepathy-filesystem

# Removed in F17
Obsoletes:      telepathy-butterfly < 0.5.15-5


%description
A Jabber/XMPP connection manager, that handles single and multi-user
chats and voice calls.


%prep
%setup -q
%patch1 -p 1 -b .build
%patch2 -p 1 -b .shebang


%if %{run_tests}
%check
#make check
%endif


%build
%configure --enable-static=no
make %{?_smp_mflags}


%install
make install DESTDIR=$RPM_BUILD_ROOT
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'

## Don't package html doc to incorrect doc directory
rm -f $RPM_BUILD_ROOT%{_docdir}/%{name}/*.html


%post -p /sbin/ldconfig


%postun -p /sbin/ldconfig


%files
%doc COPYING AUTHORS
%doc docs/*.html
%{_bindir}/%{name}-xmpp-console
%{_libexecdir}/%{name}
%{_datadir}/dbus-1/services/*.service
%{_datadir}/telepathy/managers/*.manager
%{_mandir}/man8/%{name}.8.gz
## If more connection managers make use of libdir/telepathy this
## be moved to the tp-filesystem spec file.
%dir %{_libdir}/telepathy
%dir %{_libdir}/telepathy/gabble-0
%dir %{_libdir}/telepathy/gabble-0/lib
%dir %{_libdir}/telepathy/gabble-0/plugins
%{_libdir}/telepathy/gabble-0/lib/libgabble-plugins-*.so
%{_libdir}/telepathy/gabble-0/lib/libgabble-plugins.so
%{_libdir}/telepathy/gabble-0/lib/libwocky-telepathy-gabble-*.so
%{_libdir}/telepathy/gabble-0/lib/libwocky.so
%{_libdir}/telepathy/gabble-0/plugins/libconsole.so
%{_libdir}/telepathy/gabble-0/plugins/libgateways.so


%changelog
* Fri Jun 19 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.18.2-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild

* Wed Feb 18 2015 Slavek Kabrda <bkabrda@redhat.com> - 0.18.2-4

....

    Aquí simplemente cambié la versión a 0.18.3, el Release (la versión del rpm) a 1 y eliminé las líneas que aplicaban los patches a la versión anterior. La sección files le indica al manejador de paquetes dónde debe de instalar los archivos. Es importante leer el código fuente del programa para verificar que no haya nuevas dependencias que debamos incluir, generalmente podemos encontrar un README o un INSTALL con información importante.

    Una vez hecho todo lo anterior, sólamente quedaba crear el paquete rpm utilizando para ello el comando rpmbuild -bb ~/rpmbuild/SPECS/telepathy-gabble.spec este comando compilará las fuentes y creará un nuevo paquete en el directorio /RPMS/x86_64 (arquitectura de mi equipo) llamado en este caso telepathy-gabble-0.18.3-1.fc23.x86_64.rpm listo para ser instalado.

    Espero que esta información les sea útil y les dejo el link de la documentación oficial, que aunque está un poco desactualizada puede servir de guía.

https://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/pdf/RPM_Guide/Fedora_Draft_Documentation-0.1-RPM_Guide-en-US.pdf

Saludos

domingo, 22 de noviembre de 2015

Recuperar la contraseña Root en sistemas RHEL y derivados

  Siempre me he preguntado qué pasaría si olvido la contraseña del usuario administrador o root en un sistema Linux. Sabemos que con el comando passwd un usuario puede cambiar su contraseña y que el usuario root puede cambiar la contraseña de los demás usuarios, sin embargo, ningún otro usuario sin privilegios administrativos puede cambiar la contraseña de root (naturalmente) por lo que si olvidamos la contraseña del único usuario administrativo, cómo la recuperamos?

 El proceso que describo a continuación funciona para sistemas RHEL y derivados (Fedora y Centos).

  Primero debemos tener acceso al menú de arranque del sistema. Al reiniciar el sistema operativo debemos detener el arranque automático presionando cualquier tecla en el menú del grub.


  Una vez que hemos seleccionado nuestro sistema operativo, procedemos a presionar la tecla 'e' para editar la entrada correspondiente.

  Luego vamos hasta la línea donde se encuetra el kernel.

  Nos posicionamos al final de la línea y agregamos el parámetro rd.break


  Luego de esto, procedemos a presionar Crtl-x para arrancar el sistema con la entrada editada. Esto ocasionará que el sistema se detenga y nos arroje un shell dentro del initramfs, antes de montar el resto del sistema.


  Dentro de este shell podemos montar el root filesystem, simplemente necesitamos ejecutar el comando

mount -o rw, remount /sysroot

  De hecho dentro de sysroot se encuentran todos los archivos del sistema, así que una vez que los hemos montado en modo lectura-escritura podemos utilizar el comando passwd y cambiar la contraseña del usuario root.

  Primero debemos cambiar al root /sysroot ejecutando el comando

chroot /sysroot

  Una vez hecho esto, podemos ejecutar el comando passwd y cambiar la contraseña del usuario root.

  El último paso consiste en hacer un relabel de los archivos del sistema linux, ya que si estamos utilizando RHEL o derivados este procedimiento habrá cambiado el contexto del archivo passwd, lo que nos dará problemas con SELinux.

  Para hacer el relabel automático en el próximo arranque, sólo necesitamos crear un archivo vacío en el directorio raíz llamado .autorelabel

touch /.autorelabel

  Listo, solamente necesitamos continuar con el proceso normal de arranque, para ello utilizamos el comando exit para salir del chroot y del ram filesystem.

Espero que les sea útil.

martes, 3 de noviembre de 2015

Cómo bootear una distro instalada en un folder (chroot)


En el post anterior explicaba como instalar una distribución Linux dentro de un folder (chroot) en otra distro sin necesidad de crear una nueva partición.

En este post voy a explicar cómo escoger cuál de los dos sistemas bootear desde el grub de Linux.

El primer paso consiste en crear un archivo dentro del chroot al que llamaremos chrootinit, la idea es que este sea el primer programa en ejecutarse después de que el kernel termine de arrancar. Normalmente el primer proceso en ejecutarse es init y se encarga de configurar y arrancar los diferentes procesos en nuestro sistema operativo, últimente la mayor parte de distros han migrado a systemd, por lo que init ahora es un link que apunta a systemd.

Como podemos observar, en el chroot tenemos lo necesario para bootear nuestro sistema operativo, el vmlinuz que es la imagen comprimida del kernel y la imagen initramfs que es el sistema de archivos que carga el kernel en la memoria ram para poder ejecutar varios procesos. Los mismos se encuentran dentro del folder boot en nuestro chroot.

El contenido del archivo chrootinit es el siguiente:

Son solamente dos líneas de código que se encargan de montar la raíz del sistema de archivos en modo escritura-lectura y luego ejecuta el comando chroot pasándole la ubicación de nuestro sistema para después ahora sí, ejecutar el proceso init que normalmente se hubiera ejecutado de primero.

Ahora solo queda crear una nueva entrada en el grub, para que éste nos dé a escoger el sistema que deseamos bootear. Para eso necesitamos pasarle la ubicación del kernel, el initramfs y nuestro script chrootinit.

Para lograr esto tuve que copiar varias cosas de una de las entradas del grub.

Si antes de arrancar el sistema operativo que tenemos instalado presionamos la tecla 'e' podemos ver los parámetros que se le pasan al bootloader en dicha entrada:


Esto es una característica bastante útil del grub, ya que nos permite editar la configuración de las diferentes entradas directamente y probar los cambios sin hacerlos permanentes.

Después de que obtuve los resultados deseados simplemente ingresé la información en /etc/grub.d/40_custom

Esto lo hice dentro de Ubuntu que es el sistema que tenía instalado originalmente. Como se puede ver, dentro de los parámetros que se le pasan al kernel está nuestro script /arch/boot/chrootinit que será lo primero que se ejecutará en el espacio de usuario.

Ahora es sólo cuestión de correr update-grub y reiniciar el sistema



Y después de escoger 'Arch Linux chroot' ya podemos loguearnos al sistema:

Es importante señalar que el usuario había sido creado anteriormente dentro del chroot :)

Espero que les resulte útil la información.

Saludos

sábado, 31 de octubre de 2015

Cómo Instalar otra distro Linux en la misma partición

  En este artículo pretendo mostrar cómo instalar otra distribución Linux dentro en un sistema que ya tenga instalado alguna versión de este sistema operativo.

  Para esta demostración me decidí por instalar Arch Linux dentro de Ubuntu Trusty 14.04.3 debido a que ya existe un script que nos instala todo lo necesario dentro del folder o la ruta que le indiquemos al mismo, aunque también es posible instalar otras distribuciones basadas en debian por ejemplo usando herramientas como debootstrap y otras similares. El script para instalar Arch Linux lo podemos encontrar aquí

arch-bootstrap.sh

Simplemente se necesita crear un folder donde irán todos los archivos de la distribución, en mi caso:

#mkdir /arch

Luego de esto se ejecuta el script que bajamos anteriormente indicándole la arquitectura que deseamos utilizar y la ubicación del folder donde realizaremos la instalación:

#bash arch-bootstrap.sh -a x86_64 /arch

lo que comenzará la instalación del sistema, es necesario ejecutar este script como root o usando sudo.

luego de que este proceso haya concluido, procedemos a montar los siguientes directorios y a entrar en el chroot

#mount --rbind /proc /arch/proc
#mount --rbind /sys /arch/sys
#mount --rbind /dev /arch/dev
#chroot /arch

después de esto tuve que montar el sistema de archivos root ("/") dentro del chroot para que varias cosas funcionaran.

para eso tuve que buscar el UUID del disco donde instalé el chroot usando el comando blkid, una vez que obtuve esta información simplemente escribí una entrada en el archivo de configuración /etc/fstab:

UUID="74837d6d-2dbd-4187-9cbe-31f906e4e98f" / defaults 0 0

como esta partición no se monta automáticamente ya que no estamos booteando el sistema operativo, es necesario ejecutar como superusario el siguiente comando:

#mount -a

este comando se encarga de montar todas las particiones que se encuentran dentro del archivo /etc/fstab

luego de todo lo anterior, es necesario inicializar la base de datos de llaves gpg de el manejador de paquetes pacman, para poder comenzar a instalar paquetes dentro de nuestro chroot

#pacman-key --init

Es importante destacar que este proceso puede tomar bastante tiempo en ejecutarse a menos que generemos entropía para las llaves presionando teclas aleatorias en el teclado hasta que el comando termine de ejecutarse.

Finalmente para sincronizar la base de datos ejecutamos

#pacman-key --populate archlinux

Después de lo cual podemos instalar el sistema base

#pacman -S base

Segunda parte