Product SiteDocumentation Site

5.2. Metainformación de un paquete

Un paquete Debian no es sólo un compendio de archivos a instalar. Forma parte de un todo más grande y describe su relación con otros paquetes Debian (requisitos, dependencias, conflictos, sugerencias). También provee scripts que permiten la ejecución de órdenes en diferentes etapas del ciclo de vida del paquete (instalación, actualización, eliminación). Estos datos utilizados por las herramientas de gestión de paquetes no son parte del software empaquetado, son lo que se denomina «metainformación» (información sobre otra información) dentro del paquete.

5.2.1. Descripción: el archivo control

Este archivo usa una estructura similar a las cabeceras de correo electrónico (según define RFC 2822) y se describe con detalle en la Normativa de Debian y en las páginas de manual deb-control(5) y deb822(5).
Por ejemplo el archivo control de apt se ve de la siguiente forma:
$ apt-cache show apt
Package: apt
Version: 2.2.4
Installed-Size: 4337
Maintainer: APT Development Team <deity@lists.debian.org>
Architecture: amd64
Replaces: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~)
Provides: apt-transport-https (= 2.2.4)
Depends: adduser, gpgv | gpgv2 | gpgv1, libapt-pkg6.0 (>= 2.2.4), debian-archive-keyring, libc6 (>= 2.15), libgcc-s1 (>= 3.0), libgnutls30 (>= 3.7.0), libseccomp2 (>= 2.4.2), libstdc++6 (>= 9), libsystemd0
Recommends: ca-certificates
Suggests: apt-doc, aptitude | synaptic | wajig, dpkg-dev (>= 1.17.2), gnupg | gnupg2 | gnupg1, powermgmt-base
Breaks: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~), aptitude (<< 0.8.10)
Descripción-sp: administrador de paquetes de línea de comandos
 Este paquete proporciona herramientas de línea de comandos para buscar y
 gestionar y consultar información sobre paquetes
 como acceso de bajo nivel a todas las funciones de la biblioteca libapt-pkg.
 .
 Estos incluye:
  * apt-get para la recuperación de paquetes e información sobre ellos
    de fuentes autenticadas y para la instalación, actualización y
    eliminación de paquetes junto con sus dependencias
  * apt-cache para consultar información disponible sobre paquetes
    instalados así como instalables
  * apt-cdrom usar medios extraíbles como fuente para paquetes
  * apt-config como interfaz para los ajustes de configuración
  * apt-key como interfaz para gestionar claves de autenticación
Description-md5: 9fb97a88cb7383934ef963352b53b4a7
Tag: admin::package-management, devel::lang:ruby, hardware::storage,
 hardware::storage:cd, implemented-in::c++, implemented-in::perl,
 implemented-in::ruby, interface::commandline, network::client,
 protocol::ftp, protocol::http, protocol::ipv6, role::program,
 scope::application, scope::utility, suite::debian, use::downloading,
 use::organizing, use::playing, use::searching, works-with-format::html,
 works-with::audio, works-with::software:package, works-with::text
Section: admin
Priority: required
Filename: pool/main/a/apt/apt_2.2.4_amd64.deb
Size: 1491328
MD5sum: 24d53e8dd75095640a167f40476c0442
SHA256: 75f07c4965ff0813f26623a1164e162538f5e94defba6961347527ed71bc4f3d
Echemos una cuidadosa mirada al propósito de algunos de los campos enumerados en el comando anterior.

5.2.1.1. Dependencias: el campo Depends

Las dependencias están definidas en el campo Depends en la cabecera del paquete. Es una lista de condiciones a cumplir para que el paquete funcione correctamente. Las herramientas como apt utilizan esta información para instalar las bibliotecas, herramientas, controladores, etc. necesarios, en versiones apropiadas para satisfacer las dependencias del paquete a instalar. Para cada dependencia es posible restringir el rango de versiones que cumplen dicha condición. En otras palabras, es posible expresar el hecho de que necesitamos el paquete libc6 en una versión igual o mayor a «2.15» (escrito como «libc6 (>= 2.15)». Los operadores de comparación de versiones son los siguientes:
  • <<: menor que;
  • <=: menor o igual que;
  • =: igual a (note que «2.6.1» no es igual a «2.6.1-1»);
  • >=: mayor o igual que;
  • >>: mayor que.
En una lista de condiciones a cumplir, la coma sirve como separador. Debe interpretarse como un «and» lógico. En las condiciones una barra vertical («|») expresa un «or» lógica (es un «or» inclusivo, no un exclusivo “either/or”). Tiene más prioridad que «and» y se puede usar tantas veces como sea necesario. Por lo tanto, la dependencia «(A o B) y C» se escribe A | B, C. Por otro lado, la expresión «A o (B y C)» debe escribirse «(A o B) y (A o C)» ya que el campo Depends no permite paréntesis que cambien el orden de las prioridades entre los operadores lógicos «or» e «and». Por lo tanto, se escribiría A | B, A | C.
El sistema de dependencias es un buen mecanismo para garantizar el funcionamiento de un programa, pero tiene otro uso con los «metapaquetes». Éstos son paquetes vacíos que sólo describen dependencias. Facilitan la instalación de un grupo consistente de programas preseleccionados por el desarrollador del metapaquete; como tal apt install meta-package instalará automáticamente todos estos programas utilizando las dependencias del metapaquete. Los paquetes gnome, kde-full y linux-image-amd64, por ejemplo, son metapaquetes.

5.2.1.2. Conflictos: el campo Conflicts

El campo Conflicts indica que un paquete no puede instalarse simultáneamente con otro. La razón más común es que ambos paquetes contienen un archivo con el mismo nombre y ruta, proveen el mismo servicio en el mismo puerto TCP o estorban el funcionamiento del otro.
dpkg se negará a instalar un paquete si genera un conflicto con un paquete ya instalado, excepto si el nuevo paquete especifica que «reemplazará» al paquete instalado en cuyo caso dpkg elegirá reemplazar el paquete existente con el nuevo. apt siempre seguirá sus instrucciones: si desea instalar un nuevo paquete ofrecerá automáticamente desinstalar el paquete que genera problemas.

5.2.1.3. Incompatibilidades: el campo Breaks

El campo Breaks tiene un efecto similar al del campo Conflicts pero con un significado especial. Indica que la instalación de un paquete «romperá» otro paquete (o versiones particulares del mismo). En general, esta incompatibilidad entre dos paquetes es temporal y la relación Breaks se refiere específicamente a las versiones incompatibles.
dpkg se negará a instalar un paquete que rompe un paquete ya instalado y apt intentará resolver el problema actualizando a una nueva versión el paquete que se rompería (que se asume estaría arreglado y, por lo tanto, sería compatible nuevamente).
Este tipo de situaciones pueden ocurrir en casos de actualizaciones que no sean compatibles con versiones anteriores: este es el caso si una nueva versión ya no funciona con la versión anterior y causa un mal funcionamiento en otros programas si no se toman medidas especiales. El campo Breaks previene que el usuario se tope con estos problemas.

5.2.1.4. Elementos provistos: el campo Provides

Este campo introduce el concepto interesante de un «paquete virtual». Tiene muchos roles pero hay dos particularmente importantes. El primero consiste en utilizar un paquete virtual para asociar un servicio genérico con él (el paquete «provee» el servicio). El segundo indica que un paquete reemplaza completamente a otro y, para esos propósitos, también puede satisfacer las dependencias que otros satisfacen. Es posible, entonces, crear un paquete substituto sin tener que utilizar el mismo nombre de paquete.
5.2.1.4.1. Proveyendo un «servicio»
Discutamos con más detalles el primer caso con un ejemplo: se dice que todos los servicios de correo, como postfix o sendmail «proveen» el paquete virtual mail-transport-agent. Por lo tanto, cualquier paquete que necesite este servicio para funcionar (por ejemplo, un gestor de listas de correo como smartlist o sympa) simplemente indican en sus dependencias que requieren de mail-transport-agent en lugar de especificar una lista larga y aún incompleta de posibles soluciones (por ejemplo postfix | sendmail | exim4 | ...). Lo que es más, es inútil instalar dos servidores de correo en el mismo equipo, por lo que cada uno de estos paquetes declara un conflicto con el paquete virtual mail-transport-agent. Un conflicto de un paquete con sí mismo es ignorado por el sistema, pero esta técnica prohibirá la instalación de dos servidores de correo simultáneamente.
5.2.1.4.2. Intercambio con otro paquete
El campo Provides es también interesante cuando se incluye el contenido del paquete en un paquete más grande. Por ejemplo, el módulo Perl libdigest-md5-perl era un módulo opcional en Perl 5.6 y se integró como estándar en Perl 5.8 (y versiones siguientes, está presente en como 5.32.1 Bullseye). Como tal, el paquete perl desde su versión 5.8 declara Provides: libdigest-md5-perl para que se cumplan las dependencias de este paquete si el usuario tiene Perl 5.8 (o una versión más reciente). El paquete libdigest-md5-perl se eliminó, ya que carecía de sentido cuando se retiraron las versiones antiguas de Perl.
Utilización del campo Provides para no romper dependencias

Figura 5.1. Utilización del campo Provides para no romper dependencias

Esta funcionalidad es muy útil ya que nunca es posible anticipar los caprichos del desarrollo y es necesario que sea posible adaptarse a cambios de nombre y otros reemplazos automáticos de software obsoleto.
5.2.1.4.3. Limitaciones anteriores
Los paquetes virtuales solían sufrir algunas limitaciones, la más importante de ellas era la ausencia de un número de versión. Volviendo al ejemplo anterior, una dependencia como Depends: libdigest-md5-perl (>= 1.6) nunca se considerará como satisfecha por el sistema de empaquetado aún en presencia de Perl 5.10 — aunque de hecho es más que probable que esté satisfecha. Desconociendo esto el sistema de paquetes selecciona la opción menos arriesgada, asumiendo que las versiones no coinciden.
Se ha superado esta limitación dpkg 1.17.11 y ya no es relevante. Los paquetes, como perl 5.32.1, pueden asignar una versión a los paquetes virtuales que proveen, tales como Provides: libdigest-md5-perl (= 2.55.01), y así permitir que otros paquetes utilicen dependencias versionadas.

5.2.1.5. Reemplazo de archivos: el campo Replaces

The Replaces field indicates that the package contains files that are also present in another package, but that the package is legitimately entitled to replace them. Without this specification, dpkg fails to install the package, stating that it cannot overwrite the files of another package (technically, it is possible to force it to do so with the --force-overwrite option, but that is not considered standard operation). This allows identification of potential problems and requires the maintainer to study the matter prior to choosing whether to add such a field.
El uso de este campo está justificado cuando cambian los nombres de los paquetes o cuando un paquete está incluido en otro. Esto sucede cuando el desarrollador decide distribuir los archivos de otra forma entre los varios paquetes binarios producidos del mismo paquete fuente: un archivo reemplazado no le corresponde al paquete antiguo, sólo al nuevo.
Si todos los archivos de un paquete instalado fueron reemplazados, se considera que se eliminó el paquete. Finalmente, este campo incita que dpkg elimie los paquetes reemplazados en casos de conflictos.

5.2.2. Scripts de configuración

Además del fichero control, el archivo control.tar.gz de cada paquete Debian puede contener una cantidad de scripts que serán ejecutados por dpkg en diferentes etapas del procesamiento de un paquete. La Normativa Debian describe los casos posibles en detalle, especificando los scripts que serán llamados y los argumentos que recibirán. Estas secuencias se pueden complicar ya que si falla uno de los scripts dpkg intentará volver a un estado satisfactorio cancelando la instalación o eliminación en curso (siempre que sea posible). Español
En general, se ejecuta el script preinst antes de la instalación del paquete, y postinst luego. De la misma forma, se invoca prerm antes de la eliminación de un paquete y postrm luego. Actualizar un paquete es equivalente a eliminar la versión anterior e instalar la nueva. No es posible describir en detalle todos los escenarios posibles aquí, pero discutiremos los dos más comunes: instalación/actualización y eliminación.

5.2.2.1. Instalación y actualización

Durante la instalación inicial y para cada actualización de un paquete, dpkg llama a los llamados scripts de mantenimiento, como prerm o scripts preinst. Estos scripts pueden realizar acciones adicionales durante las diferentes etapas del ciclo de vida de un paquete. Los nombres de los scripts precedidos por new- son los scripts de la nueva versión de un paquete que se está instalando o actualizando. Los nombres de los scripts precedidos por old- son los scripts de la versión antigua de un paquete desde el que se está actualizando.
Durante cada invocación, dpkg pasará ciertos argumentos a cada script, como upgrade nueva-versión. El script invocado puede entonces manejar los argumentos y realizar una acción particular, o ignorar los argumentos y regresar con un código de salida de 0, si no es necesario hacer nada durante ese paso. En la práctica, muchos paquetes no necesitarán realizar una acción durante cada paso del ciclo de vida. Por lo tanto, un script de configuración típico buscará un argumento en particular e ignorará todos los demás, regresando implícitamente con el código de salida 0.
Esto es lo que sucede durante una instalación (o actualización). Los argumentos old-version, new-version y last-version-configured son marcadores de posición para los números de versión reales (antiguos y nuevos) del paquete:
  1. Para una actualización, dpkg llama al script old-prerm y pasa upgrade new-version como argumentos.
  2. Aún para una actualización, dpkg luego ejecuta el script new-preinst con los argumentos upgrade old-version; para la instalación inicial, ejecuta el script new-preinst y pasa install como argumento. Se puede agregar la versión anterior en el último parámetro, si el paquete ya se instaló y eliminó desde entonces (pero no se eliminó y, por lo tanto, se conservaron los archivos de configuración).
  3. Se descomprimen los archivos del nuevo paquete. Si un archivo ya existe, es reemplazado pero se guarda una copia de respaldo de forma temporal.
  4. Para una actualización, dpkg ejecutar el script old-postrm y pasar upgrade new-version como argumentos.
  5. dpkg actualiza toda su información interna (lista de archivos, scripts de configuración, etc.) y elimina los respaldos de los archivos reemplazados. Este es el punto sin retorno: dpkg ya no tiene acceso a todos los elementos necesarios para volver al estado anterior.
  6. dpkg actualizará los archivos de configuración, pidiéndole al usuario que decida si no es capaz de administrar esta tarea automáticamente. Los detalles de este proceso son discutidos en la Sección 5.2.3, “Sumas de comprobación, lista de archivos de configuración y más.”.
  7. Finalmente, dpkg configura el paquete ejecutando el script new-postinst con los argumentos configure last-version-configured .

5.2.2.2. Eliminación de un paquete

Los pasos para eliminar un paquete son análogos a los pasos de instalación. La principal diferencia es que los scripts de eliminación del paquete se llaman:
  1. dpkg llama al script prerm y pasa el argumento remove.
  2. dpkg elimina todos los archivos del paquete, con la excepción de los archivos de configuración y scripts de mantenimiento.
  3. dpkg ejecuta el script postrm y pasa remove como argumento. Después, se eliminan todos los scripts de mantenimiento, excepto el script postrm. Si el usuario no ha utilizado la opción “purgar”, el proceso se detiene aquí.
  4. Para eliminar completamente un paquete (con la orden dpkg --purge o dpkg -P), los archivos de configuración también son eliminados junto con una cantidad de copias (*.dpkg-tmp, *.dpkg-old, *.dpkg-new) y archivos temporales; dpkg luego ejecuta el script postrm y pasa purge como argumento.
Los cuatro scripts que aparecen detallados anteriormente se complementan con un script config provisto por los paquetes que utilizan debconf para adquirir información de configuración del usuario. Durante la instalación este script define en detalle las preguntas realizadas por debconf. Se graban las respuestas en la base de datos de debconf para futuras referencias. Generalmente apt ejecuta el script antes de instalar los paquetes uno por uno para agrupar las preguntas y realizarlas todas al usuario al comienzo del proceso. Los scripts de pre y postinstalación pueden utilizar esta información para operar según los deseos del usuario.

5.2.3. Sumas de comprobación, lista de archivos de configuración y más.

Además de los scripts de mantenimiento y los datos de control ya mencionados en las secciones anteriores, el archivo control.tar.gz de un paquete Debian puede contener otros archivos interesantes.
El primer, md5sums contiene una lista sumas de verificación MD5 de todos los archivos del paquete. Su principal ventaja es que permite que dpkg-verify (que estudiaremos en Sección 14.3.4.1, “Auditoría de paquetes mediante dpkg --verify) y debsums (del paquete homónimo; ver Sección 14.3.4.2, “Auditoría de paquetes: debsums y sus límites”) chequear si estos archivos fueron modificados desde su instalación. Tener en cuenta que cuando este archivo no existe, lo que podría ser el caso de algunos paquetes más antiguos, dpkg lo generará dinámicamente en el momento de la instalación (y lo almacenará en la base de datos dpkg como otros archivos de control).
conffiles enumera los archivos del paquete que tienen que administrarse como archivos de configuración (ver también deb-conffiles(5)). El administrador puede modificar los archivos de configuración y dpkg intentará preservar estos cambios durante la actualización de un paquete.
De hecho, en esta situación, dpkg se comporta tan inteligentemente como le es posible: si el archivo de configuración estándar no fue modificado entre dos versiones, no hace nada. Si, sin embargo, el archivo cambió intentará actualizar este archivo. Son posibles dos casos: o bien el administrador no modificó el archivo, en cuyo caso dpkg automáticamente instalará la nueva versión; o el archivo fue modificado, en cuyo caso dpkg le preguntará al administrador qué versión desea utilizar (la antigua con modificaciones o la nueva provista con el paquete). Para asistirlo en esta decisión dpkg ofrece mostrar las diferencias entre las dos versiones («diff»). Si el usuario decide mantener la versión anterior, la nueva será almacenada en la misma ubicación con el sufijo .dpkg-dist. Si el usuario selecciona la nueva versión, se mantiene la versión anterior en la misma ubicación con el sufijo .dpkg-old. Otra acción posible consiste en interrumpir momentáneamente dpkg para editar el archivo e intentar rehacer las modificaciones relevantes (identificadas previamente con diff).
The control archive frequently contains other files as well, like triggers, shlibs, or symbols. These files are well described in deb-triggers(5), deb-shlibs(5), and deb-symbols(5).
Se introdujeron activadores para reducir la cantidad de actos duplicados durante la instalación del paquete, como el registro de archivos o las tareas de actualización de catálogos o bases de datos. Los paquetes pueden definir los suyos propios o activar activadores definidos. Se puede ver documentación más completa en /usr/share/doc/dpkg/triggers.txt.gz.
El sistema shlibs es una alternativa más antigua y sencilla al sistema symbols para declarar dependencias para bibliotecas compartidas. Define el nombre del paquete y la versión en la que encontrar una versión SONAME específica de una biblioteca compartida. El sistema symbols más nuevo permite definir la dependencia mediante el seguimiento de los símbolos y cuándo se han introducido o modificado en la biblioteca.