Lo hice y lo entendí

El blog de Vicente Navarro
20 feb

Gentooizar Debian con apt-build

Soy un Debianero convencido. Me encantan el apt-get, el apt-cache y el dpkg. Ubuntu también está muy bien, pero no me acaba de gustar el “te lo damos todo-todo-todo hecho”, aunque he de reconocer que cuando quieres instalar un ordenador rápidamente y que te dé poco trabajo, es, sin duda, la mejor opción. Para gustos los colores y las distribuciones… Yo personalmente me apunto a lo que dicen en Guirilandia: No pain, no gain!

Sin embargo, durante muchos meses he tenido una Gentoo en uno de mis PCs. Si quieres usar Gentoo como toca, te tienes que compilar el paquete antes de instalarlo. También puedes usar paquetes precompilados, pero para eso no nos ponemos Gentoo, ¿no? El paquete se compila -en teoría- optimizado para la máquina en cuestión, y obtenemos algo de mejora en el rendimiento. Tenemos que pagar a cambio el coste de largos tiempos de espera compilando paquetes, algo que, pese a que Gentoo me gusta en general, me desespera.

Debian es todo lo contrario en ese aspecto: los paquetes vienen compilados para 386 y la optimización, por tanto, nula (ojo, Debian sí que nos deja escoger un kernel más apropiado para nuestra plataforma, algo que sí es muy importante). En esto hemos ganado mucho con la Debian AMD64, ya que ésta sí está totalmente optimizada si tienes un procesador de 64 bits.

En Debian también podemos compilarnos los paquetes fácilmente. Por ejemplo, digamos que necesitamos ponerle un parche determinado al openssh. Sería tan sencillo como hacer:

# mkdir /path/
# cd /path/
# apt-get source openssh
# cd /path/openssh-4.3p2
# patch -p1 < /path_al_parche/parche.diff
# dpkg-buildpackage -uc -b
# dpkg -i /path/*.deb

Tenemos que tener en cuenta que de un único paquete “source” podemos obtener varios .deb. Por ejemplo, al compilar el openssl, obtenemos un deb para el openssl, otro para el libssl y otro para el libssl-dev.

Lo anterior, que es relativamente manual, se automatiza con el magnífico “apt-build“.

Para tenerlo perfectamente configurado son tres pasos:

  1. sudo apt-get install apt-build
  2. Editar el /etc/apt/apt-build.conf y poner el -Olevel (-O2 ó -O3 si eres más valiente y te atreves con posibles inestabilidades) y el -march (p.e. pentium4 o k8)
  3. Asegurarte de que en el /etc/apt/sources.list tienes repositorios de sources (deb-src)

Adicionalmente, es conveniente poner en el /etc/apt/preferences las siguientes líneas para que los nuevos paquetes compilados tengan preferencia sobre los de los repositorios oficiales:

Package: *
Pin: release o=apt-build
Pin-Priority: 990

Hecho esto, todo es tan sencillo como ejecutar “apt-build install paquete“. Yo he hecho esto para paquetes clave para los que una pequeña mejora en el rendimiento puede ser importante en ciertos momentos: el gzip, el bzip2, el ssh, el openssl… Y aunque se puede recompilar todo (“apt-build world”), yo no recomendaría recompilar cosas como la libc.

El dpkg-build en realidad lo que hace es montar un repositorio propio en el directorio /var/cache/apt-build/repository, hacer un “apt-get source” y un “dpkg-rebuildpackage” como los que he mostrado antes, y dejar los .deb recién compilados ahí para que el apt-get los encuentre. Para ello, mete la siguiente línea en el /etc/apt/sources.list:

deb file:/var/cache/apt-build/repository apt-build main

En el directorio /var/cache/apt-build/build compila los paquetes y luego los deja en el /var/cache/apt-build/repository. En este último directorio está el fichero Release que contiene:

Archive: apt-build
Component: main
Origin: apt-build
Label: apt-build
Architecture: i386

Es la línea “Origin” la que da sentido a lo que hemos puesto antes en el /etc/apt/preferences: que si tenemos un paquete de origin=apt-build y otro paquete de un repositorio ofician, tiene preferencia el nuestro.

¡Pero anda! Resulta que si queremos reinstalar los paquetes recién creados (o incluso los del repositorio oficial) no funciona:

# apt-get --reinstall install openssh-server openssh-client 
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  rssh molly-guard
The following packages will be upgraded:
  openssh-server
1 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 0 not upgraded.
Need to get 839kB of archives.
After unpacking 4096B disk space will be freed.
Do you want to continue [Y/n]? 
Get:1 http://ftp.es.debian.org etch/main openssh-client 1:4.3p2-8 [617kB]
Get:2 http://ftp.es.debian.org etch/main openssh-server 1:4.3p2-8 [222kB]
Fetched 2B in 0s (2B/s)                
Failed to fetch http://ftp.es.debian.org/debian/pool/main/o/openssh/openssh-client_4.3p2-8_i386.deb  Size mismatch
Failed to fetch http://ftp.es.debian.org/debian/pool/main/o/openssh/openssh-server_4.3p2-8_i386.deb  Size mismatch
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

Por supuesto que puedo hacer “dpkg -i” a los .deb que se han creado, pero para ese viaje no hacía falta alforjas. Tras mucho probar descubrí que el problema es que los deb que hemos creado no están firmados y el apt-get (el apt-build usa el apt-get por debajo) prefiere usar los de ftp.es.debian.org que, a su vez no tienen el tamaño que el apt-get espera (espera los tamaños de los nuevos paquetes compilados).

Tras darle mil vueltas a la página de man del “apt-get” encontré la opción “–allow-unauthenticated” que es la solución a nuestros problemas:

# apt-get --reinstall --allow-unauthenticated install openssh-server openssh-client
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  rssh molly-guard
The following packages will be upgraded:
  openssh-server
1 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 0 not upgraded.
Need to get 0B/839kB of archives.
After unpacking 4096B disk space will be freed.
Do you want to continue [Y/n]? 
WARNING: The following packages cannot be authenticated!
  openssh-client openssh-server
Authentication warning overridden.
Preconfiguring packages ...
(Reading database ... 89173 files and directories currently installed.)
Preparing to replace openssh-client 1:4.3p2-8 (using .../openssh-client_4.3p2-8_i386.deb) ...
Unpacking replacement openssh-client ...
Preparing to replace openssh-server 1:4.3p2-8 (using .../openssh-server_4.3p2-8_i386.deb) ...
Unpacking replacement openssh-server ...
Setting up openssh-client (4.3p2-8) ...
Setting up openssh-server (4.3p2-8) ...
Restarting OpenBSD Secure Shell server: sshd.

Ahora, si busco “apt-build” y “–allow-unauthenticated” en Google, encuentro que es un bug de Debian cuyo workaround es, precisamente, el que yo encontré. Lástima que lo encontrara después y no antes, pero queda la satisfacción de haber encontrado la solución por uno mismo.

Finalmente, como explica Julien Reveret, ten cuidado de que los paquetes que has compilado con apt-build y que no se actualizarán con los de los repositorios oficiales debido al /etc/apt/preferences que hemos puesto no bloqueen la actualización de otros componentes. Queda bajo nuestra responsabilidad la futura actualización de estos paquetes.

Actualización

Me comentan que Gentoo no sólo compila por optimizar, sino también por aplicar los parámetros USE, algo que ciertamente le da mucha versatilidad a la distribución.

Con el apt-build, en cambio, básicamente recompilamos el paquete con el “-O” y el “-march” que encajen con nuestra arquitectura. Además, cuando al recompilar las aplicaciones hacen el “configure”, muchas de ellas se adaptan todavía más a nuestro entorno.

Para especificar más opciones de compilación, podemos hacer un “apt-build source”, cambiamos lo que consideremos en el código (aplicando un parche, por, ejemplo) o en el Makefile y finalmente “apt-build install”. Éste último no sobreescribe los cambios que hayamos hecho.

Está claro que esto no es Gentoo, pero sí algo que nos da parte de lo bueno que tiene sin tener que renunciar a Debian.

Entradas relacionadas

4 Comentarios a “Gentooizar Debian con apt-build”

  • Quique dice:

    El artículo de Julien Reveret está traducido al castellano: apt-build – Optimice los paquetes Debian para su sistema.

  • Ringmaster dice:

    Gracias por los apuntes, ya había leído sobre el tema pero este resumen está muy bien.

  • manuel dice:

    He leido tu excelente articulo y me gustaria hacerte un par de preguntas:

    Es posible utilizar apt-build con los dvd source de debian, se supone que tus repositorios debieran ser los dvd.
    Al descargar los 3 dvd source, tendrias la posibilidad de instalar debian en cualquier arquitectura.
    Actualmente tengo un semprom 2600 64 bits, se notaria la diferencia en instalar todo con apt-build o debiera bajarme directamente los dvd para amd64.

    Saludos y muchas gracias.

  • manuel ¡Muchas gracias!

    El apt-build es un script de menos de 1000 líneas en Perl que encadena varias operaciones para lograr el efecto conjunto de una única utilidad. Para usar las fuentes, únicamente hace un apt-get source ... usando la información de las líneas deb-src del /etc/apt/sources.list. Normalmente se usan líneas como las siguientes:

    deb-src http://ftp.es.debian.org/debian/ etch main non-free contrib
    deb-src http://security.debian.org/ etch/updates main

    Pero por supuesto que se pueden usar líneas como deb-src cdrom: .... Lo único que hay que hacer es introducir los DVDs adecuados y añadirlos al sources.list usando el comando apt-cdrom.

    Respecto a la optimización, recompilar una Debian 386 a AMD64 es una tarea titánica que además no creo que se pudiera hacer, ya que cambian muchas librerías clave. Es mucho mejor directamente usar la Debian AMD64 que ya viene optimizada al máximo para estos procesadores.

Tema LHYLE09, creado por Vicente Navarro