El paquet Debian no és només un arxiu de fitxers destinats a la instal·lació. Forma part d'un conjunt més gran i descriu la seva relació amb altres paquets de Debian (requisits, dependències, conflictes, suggeriments). També proporciona «scripts» que permeten l'execució d'ordres en diferents etapes en el cicle de vida del paquet (instal·lació, actualització, eliminació). Aquestes dades són utilitzades per les eines de gestió de paquets però no formen part del programari empaquetat; són, dins del paquet, el que s'anomena la seva “meta-informació” ‐ informació sobre altra informació.
5.2.1. Descripció: l'arxiu control
Aquest fitxer utilitza una estructura similar a les capçaleres de correu electrònic (com es defineixen a
RFC 2822) i es descriu completament a la Normativa de Debian i a les pàgines del manual
deb-control(5) i
deb822(5).
Per exemple, el control
de apt, es veu d'aquesta manera:
$
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)
Description-en: commandline package manager
This package provides commandline tools for searching and
managing as well as querying information about packages
as a low-level access to all features of the libapt-pkg library.
.
These include:
* apt-get for retrieval of packages and information about them
from authenticated sources and for installation, upgrade and
removal of packages together with their dependencies
* apt-cache for querying available information about installed
as well as installable packages
* apt-cdrom to use removable media as a source for packages
* apt-config as an interface to the configuration settings
* apt-key as an interface to manage authentication keys
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
Farem ara una mirada més detallada a la finalitat d'alguns dels camps enumerats per l'ordre anterior.
5.2.1.1. Dependències: el camp Depends
Les dependències es defineixen al camp Depends
de la capçalera del paquet. És una llista de condicions que cal complir perquè el paquet funcioni correctament. Aquesta informació és utilitzada per eines com apt
per tal d'instal·lar les biblioteques, eines, controladors, etc., en les versions apropiades que compleixin les dependències del paquet que s'instal·larà. Per a cada dependència és possible restringir el rang de versions que compleixen aquesta condició. En altres paraules, és possible expressar el fet que necessitem el paquet libc6 en una versió igual o superior a “2.15” (escrit “libc6 (>= 2.15)
”). Els operadors de comparació de versions són els següents:
En una llista de condicions a complir, la coma serveix com a separador. S'ha d'interpretar com una “i” lògica. En condicions, la barra vertical (“|”) expressa un “o” lògic (és a dir, un “o” inclusiu, no un “o” exclusiu). Té més prioritat que “i”, i es pot utilitzar tantes vegades com sigui necessari. Per tant, la dependència “(A o B) i C” s’escriu
A | B, C
. Per contra, l'expressió “A o (B i C)” s'ha d'escriure com a “(A o B) i (A o C)”, ja que el camp
Depends
no tolera parèntesis que canvien l'ordre de prioritats entre els operadors lògics “o” and “i”. Per tant, s'escriuria
A | B, A | C
.
El sistema de dependències és un bon mecanisme per garantir el funcionament d'un programa, però té un altre ús amb “metapaquets”. Aquests són paquets buits que només descriuen dependències. Faciliten la instal·lació d'un grup coherent de programes preseleccionats pel mantenidor del metapaquet; com a tal, apt install metapaquet
instal·larà automàticament tots aquests programes usant les dependències del metapaquet. Els paquets gnome, kde-full i linux-image-amd64 són exemples de metapaquets.
5.2.1.2. Conflictes: el camp Conflicts
El camp Conflicts
indica quan un paquet no es pot instal·lar simultàniament amb un altre. Les raons més comunes per a això són que tots dos paquets inclouen un arxiu del mateix nom i ruta («path»), o proporcionen el mateix servei en el mateix port TCP, o dificulten l'operació de l'altre.
dpkg
es negarà a instal·lar un paquet si provoca un conflicte amb un paquet ja instal·lat, excepte si el nou paquet especifica que “reemplaçarà” el paquet instal·lat, en aquest cas dpkg
optarà per reemplaçar el paquet antic amb el nou. apt
sempre segueix les vostres instruccions: si trieu instal·lar un nou paquet, s'oferirà automàticament per desinstal·lar el paquet que planteja un problema.
5.2.1.3. Incompatibilitats: el camp Breaks
El camp Breaks
té un efecte similar al del camp Conflicts
, però amb un significat especial. Indica que la instal·lació d'un paquet “trencarà” un altre paquet (o certes versions concretes). En general, aquesta incompatibilitat entre dos paquets és transitòria, i la relació Breaks
es refereix específicament a les versions incompatibles.
dpkg
es negarà a instal·lar un paquet que trenca un paquet ja instal·lat, i apt
intentarà resoldre el problema actualitzant el paquet que es trencaria a una versió més nova (que se suposa que estaria resolt i, per tant, seria compatible de nou).
Aquest tipus de situació pot ocórrer en el cas d'actualitzacions sense compatibilitat cap enrere: aquest és el cas si la nova versió ja no funciona amb la versió més antiga, i causa un mal funcionament en un altre programa sense fer disposicions especials. El camp Breaks
evita que l'usuari es trobi amb aquests problemes.
5.2.1.4. Ítems proveïts: el camp Provides
Aquest camp introdueix el molt interessant concepte de “paquet virtual”. Té moltes funcions, però dues són d'especial importància. El primer rol consisteix en l'ús d'un paquet virtual per associar un servei genèric amb ell (el paquet “proveeix” el servei). El segon indica que un paquet substitueix completament un altre i que, per a aquest propòsit, també pot satisfer les dependències que l'altre podria satisfer. Per tant, és possible crear un paquet de substitució sense haver d'utilitzar el mateix nom de paquet.
5.2.1.4.1. Proveint un “servei”
Discutirem el primer cas amb més detall amb un exemple: tots els servidors de correu, com postfix o sendmail es diu que “proveeixen” paquet virtual mail-transport-agent. Per tant, qualsevol paquet que necessiti aquest servei per ser funcional (p. ex. un gestor de llistes de correu, com smartlist o sympa) simplement declara a les dependències que requereix un mail-transport-agent en lloc d'especificar una llarga però incompleta llista de solucions possibles(p.ex. postfix | sendmail | exim4 | …
). A més, és inútil instal·lar dos servidors de correu en la mateixa màquina, raó per la qual cadascun d'aquests paquets declara un conflicte amb el paquet virtual mail-transport-agent. El sistema ignora conflictes entre un paquet i ell mateix, però aquesta tècnica prohibirà la instal·lació simultània de dos servidors de correu.
5.2.1.4.2. Intercanviabilitat amb un altre paquet
El camp Provides
també és interessant quan el contingut d'un paquet està inclòs en un paquet més gran. Per exemple, el mòdul Perl libdigest-md5-perl va ser un mòdul opcional en Perl 5.6, i s'ha integrat com a estàndard a Perl 5.8 (i versions posteriors, com ara 5.32.1 present a Bullseye). Com a tal, el paquet perl declara des de la versió 5.8 Provides: libdigest-md5-perl
de manera que les dependències d'aquest paquet es compleixin si l'usuari té Perl 5.8 (o més recent). El paquet libdigest-md5-perl s'ha eliminat, ja que ja no tenia cap propòsit quan també es van eliminar les versions antigues de Perl.
Aquesta característica és molt útil, ja que mai és possible anticipar els capricis del desenvolupament, i és necessari ser capaç d'ajustar-se a canvis de nom, i altres reemplaçaments automàtics, de programari obsolet.
5.2.1.4.3. Antigues limitacions
Els paquets virtuals solien patir algunes limitacions, essent la més significativa l'absència d'un número de versió. Per tornar a l'exemple anterior, una dependència com Depends: libdigest-md5-perl (>= 1.6)
, malgrat la presència de Perl 5.10, mai no s'hauria considerat com a satisfeta pel sistema de paquets — mentre que de fet és força probable que ho estigui. Sense saber-ho, el sistema de paquets ha escollit l'opció menys arriscada, suposant que les versions no coincideixen.
Aquesta limitació s'ha aixecat a dpkg 1.17.11 i ja no és rellevant. Els paquets, com perl 5.32.1, poden assignar una versió als paquets virtuals que proporcionen, com ara Provides: libdigest-md5-perl (= 1.8)
, i d'aquesta manera permete que altres paquets usin dependències versionades.
5.2.1.5. Substituint arxius: el camp Replaces
El camp Replaces
indica que el paquet conté fitxers que també estan presents en un altre paquet, però que el paquet té dret legítim a reemplaçar-los. Sense aquesta especificació, dpkg
falla a l'instal·lar el paquet, afirmant que no pot sobreescriure els fitxers d'un altre paquet (tècnicament, és possible forçar-ho amb l'opció --force-overwrite
, però això no es considera una operació estàndard). Aquest fet permet la identificació de problemes potencials i requereix que el mantenidor estudiï l'assumpte abans de decidir si afegir aquest camp.
L'ús d'aquest camp està justificat quan els noms dels paquets canvien o quan s'inclou un paquet en un altre. Això també passa quan el mantenidor decideix distribuir fitxers de manera diferent entre diversos paquets binaris produïts a partir del mateix paquet font: un fitxer substituït ja no pertany al paquet antic, sinó només al nou.
Si s'han substituït tots els fitxers d'un paquet instal·lat, es considera que el paquet s'ha eliminat. Finalment, aquest camp també encoratja a dpkg
a eliminar el paquet substituït si hi ha conflictes.
5.2.2. Scripts de configuració
A més del fitxer
control
, el fitxer
control.tar.gz
de cada paquet de Debian pot contenir un seguit d'scripts, cridats per
dpkg
en diferents etapes en el processament d'un paquet. La Normativa de Debian descriu els casos possibles amb detall, especificant els scripts cridats i els arguments que reben. Aquestes seqüències poden ser complicades, ja que si un dels scripts falla,
dpkg
intentarà tornar a un estat satisfactori cancel·lant la instal·lació o l'eliminació en curs (en la mesura que sigui possible).
En general, l'script preinst
s'executa abans de la instal·lació del paquet, mentre que el postinst
ho fa després. De la mateixa manera, prerm
s'invoca abans de suprimir un paquet i postrm
després. Una actualització d'un paquet és equivalent a l'eliminació de la versió anterior i la instal·lació del nou. No és possible descriure detalladament tots els escenaris possibles, però debatrem els dos més comuns: una instal·lació/actualització i una supressió.
5.2.2.1. Instal·lació i actualització
Durant la instal·lació inicial i per a cada actualització d'un paquet, dpkg
crida els anomenats scripts del mantenidor o «maintainer scripts», com ara els scripts prerm
o preinst
. Aquests scripts poden realitzar accions addicionals durant les diferents etapes del cicle de vida d'un paquet. Els noms dels scripts precedits per new-
són els scripts de la nova versió d'un paquet que s'està instal·lant o actualitzant. Els noms dels scripts precedits per old-
són els scripts de la versió antiga d'un paquet que s'està actualitzant.
Durant cada invocació, dpkg
passarà certs arguments a cada script com ara upgrade nova-versió
. L'script invocat pot llavors gestionar els arguments i realitzar una acció en particular, o ignorar els arguments i tornar amb un codi de sortida 0
si no cal fer res en aquest pas. A la pràctica, molts paquets no necessitaran realitzar accions durant cada pas del cicle de vida. Així, un script de configuració típic comprovarà un argument en particular i ignorarà tots els altres, retornant implícitament amb el codi de sortida 0
.
Això és el que passa durant una instal·lació (o una actualització). Els arguments versió-antiga, versió-nova i darrera-versió-configurada són substituts dels números de versió reals (antiga i nova) del paquet:
Per a una actualització, dpkg
executa l'script old-prerm
i passa upgrade versió-nova
.
I encara per a una actualització, dpkg
executa després l'script new-preinst
amb els paràmetres upgrade versió-antiga
; per a la primera instal·lació, executa l'script new-preinst
i li passa install
com a paràmetre. Pot afegir la versió antiga com a darrer paràmetre, si el paquet ja havia estat instal·lat i eliminat (però no purgat, amb la qual cosa els fitxers de configuració s'haurien mantingut).
Els nous fitxers del paquet són extrets. Si ja existeix un fitxer, se substitueix, però se'n fa una còpia de seguretat temporal.
Per a una actualització, dpkg
executa l'script old-postrm
i li passa upgrade versió-nova
com a paràmetres.
dpkg
actualitza totes les dades internes (llista de fitxers, scripts de configuració, etc.) i elimina les còpies de seguretat dels fitxers substituïts. Aquest és el punt de no retorn: dpkg
ja no té accés a tots els elements necessaris per tornar a l'estat anterior.
Finalment, dpkg
configura el paquet executant l'script new-postinst
amb els paràmetres configure darrera-versió-configurada
.
5.2.2.2. Eliminació de paquets
Els passos per a eliminar un paquet són anàlegs als d'instal·lació. La principal diferència és que són els scripts d'eliminació del paquet els que s'executen:
dpkg
executa l'script prerm
i li passa el paràmetre remove
.
dpkg
esborra tots els fitxers del paquet, amb l'excepció dels fitxers de configuració i els scripts del mantenidor.
dpkg
executa l'script postrm
i li passa remove
com a paràmetre. Després, tots els scripts del mantenidor, excepte l'script postrm
, són eliminats. Si l'usuari no ha utilitzat l'opció «purge» (“purgar”), el procés s'atura aquí.
Per a una purga completa del paquet (comanda emesa amb dpkg --purge
o dpkg -P
), els fitxers de configuració també s'eliminen, així com un cert nombre de còpies (*.dpkg-tmp
, *.dpkg-old
, *.dpkg-new
) i arxius temporals; a continuació dpkg
executa l'script postrm
i li passa purge
com a paràmetre.
Els quatre scripts detallats anteriorment es complementen amb un script config
, usat per paquets que utilitzen debconf
per obtenir informació de l'usuari per a la configuració. Durant la instal·lació, aquest script defineix detalladament les preguntes fetes per debconf
. Les respostes es registren a la base de dades de debconf
per a futures referències. L'script és executat generalment per apt
abans d'instal·lar paquets, un per un, per agrupar totes les preguntes i fer-les totes alhora a l'usuari al començament del procés. Els scripts de pre- i post-instal·lació poden utilitzar aquesta informació per operar segons els desitjos de l'usuari.
5.2.3. Sumes de verificació («checksums»), llista de fitxers de configuració, i altres.
A més dels scripts del mantenidor i les dades de control ja esmentats en les seccions anteriors, l'arxiu control.tar.gz
d'un paquet Debian pot contenir altres fitxers interessants.
El primer,
md5sums
, conté les sumes de verificació MD5 per a tots els arxius del paquet. El seu avantatge principal és que permet a
dpkg --verify
(que estudiarem a
Secció 14.3.4.1, «Auditar els paquets amb dpkg --verify
») i a
debsums
(del paquet del mateix nom; vegeu
Secció 14.3.4.2, «Auditoria de paquets: debsums
i les seves limitacions») comprovar si aquests fitxers han estat modificats des de la seva instal·lació. Tingueu en compte que quan aquest fitxer no existeix, que pot ser el cas en alguns paquets antics,
dpkg
el generarà dinàmicament en el moment de la instal·lació (i l'emmagatzemarà a la base de dades de dpkg igual que altres fitxers de control).
El fitxer conffiles
llista els fitxers del paquet que s'han de gestionar com a fitxers de configuració (vegeu tambédeb-conffiles(5) ). Els fitxers de configuració poden ser modificats per l'administrador, i dpkg
intentarà conservar aquests canvis durant una actualització del paquet.
De fet, en aquesta situació, dpkg
es comporta tant intel·ligentment com sigui possible: si el fitxer de configuració estàndard no ha canviat entre les dues versions, no fa res. No obstant això, si l'arxiu ha canviat, intentarà actualitzar aquest arxiu. Hi ha dos casos possibles: o bé l'administrador no ha tocat aquest fitxer de configuració, en aquest cas dpkg
instal·la automàticament la nova versió; o el fitxer ha estat modificat, en aquest cas dpkg
demana a l'administrador quina versió vol utilitzar (l'antiga amb modificacions o la nova proporcionada amb el paquet). Per ajudar a prendre aquesta decisió, dpkg
ofereix mostrar un “diff
” que mostra les diferències entre les dues versions. Si l'usuari tria mantenir la versió antiga, la nova s'emmagatzemarà en la mateixa ubicació en un fitxer amb el sufix .dpkg-dist
. Si l'usuari tria la nova versió, l'antiga es conserva en un fitxer amb el sufix .dpkg-old
. Una altra acció disponible consisteix en interrompre momentàniament dpkg
per editar el fitxer i intentar tornar a refer les modificacions rellevants (identificades prèviament amb diff
).
Sovint el fitxer de control conté també altres fitxers, com triggers
, shlibs
, o symbols
. Aquests fitxers estan ben explicats a deb-triggers(5), deb-shlibs(5), i deb-symbols(5).
Es van introduir els activadors («triggers» en anglès) per reduir la quantitat d'esdeveniments duplicats durant la instal·lació de paquets, com ara el registre de fitxers o tasques d'actualització de catàleg o bases de dades. Els paquets poden definir els seus propis activadors o activar-ne altres ja definits. Es pot trobar una documentació més completa a
/usr/share/doc/dpkg/triggers.txt.gz
.
El sistema shlibs
és una alternativa més antiga i senzilla al sistema de symbols
per declarar les dependències de biblioteques compartides. Defineix el nom i la versió del paquet en què es troba una versió específica de SONAME d'una biblioteca compartida. El nou sistema de symbols
permet definir la dependència seguint els símbols i quan aquests han estat introduïts o canviats a la biblioteca.