Dépôts APT locaux en entreprise
Vincent Bernat
Distribuer de manière efficace des logiciels sur l’ensemble d’une plateforme peut être ardu. Chaque distribution fournit un gestionnaire de paquets qui est généralement bien adapté à cette tâche. Dans le cas de Debian ou d’une distribution dérivée, il s’agit d’APT.
Certains logiciels ne sont pas présent dans les dépôts officiels ou peuvent être disponibles dans une version trop ancienne. La mise en place d’un dépôt local permet de contourner cet écueil.
Ce qui est présenté ici a été mis en place pour Dailymotion et a été fortement inspiré du travail de Raphaël Pinson chez Orange.
Configuration des dépôts locaux#
Les dépôts à mettre en place peuvent se classer dans trois catégories :
-
Les miroirs de distributions. Ils permettent d’économiser de la bande passante, d’obtenir un meilleur débit et un accès permanent même lorsque l’accès à Internet est perturbé.
-
Les dépôts maisons pour vos propres paquets avec la possibilité de passer par une zone de test pour valider les paquets sur quelques machines avant de les pousser en production.
-
Les miroirs pour les dépôts non officiels, tels que des PPA Ubuntu. Pour éviter tout changement inattendu, de tels dépôts sont aussi dôtés d’une zone de test et d’une zone de production.
Avant de continuer, il est important de s’accorder sur la terminologie
à employer. Examinons une ligne issue de mon /etc/apt/sources.list
:
deb http://ftp.debian.org/debian/ unstable main contrib non-free
Dans cet exemple, http://ftp.debian.org/debian/
est un dépôt et
unstable
est une distribution. Une distribution est divisée en
un certain nombre de composants. Nous en avons ici trois : main
,
contrib
et non-free
.
La mise en place des différents dépôts se fera avec le logiciel reprepro. Ce n’est pas la seule solution disponible mais il est à la fois plutôt versatile et simple à mettre en place. reprepro ne gère qu’un seul dépôt. Le premier choix à effectuer est donc de savoir comment répartir les paquets dans les dépôts, les distributions et les composants.
Mise à jour (06.2019)
aptly est une alternative à reprepro. Il gère plusieurs dépôts. Il propose une API HTTP et il peut conserver plusieurs versions d’un même paquet. Pour un miroir complet d’une distribution, reprepro reste plus performant, mais pour le reste, je vous conseille d’utiliser aptly.
Voici quelques billes pour choisir :
- Un dépôt ne peut pas contenir deux paquets identiques (même nom, même version, même architecture).
- À l’intérieur d’un composant, il n’est possible d’avoir qu’une seule version d’un paquet.
- Habituellement, une distribution est un sous-ensemble des
versions tandis qu’un composant est un sous-ensemble des
paquets. Par exemple, dans Debian, la distribution
unstable
permet d’obtenir des paquets dans des versions très récentes tandis que le composantmain
permet de se limiter aux paquets respectant la DFSG.
En partant sur plusieurs dépôts, il faudra gérer plusieurs instances de reprepro et la copie entre deux instances se fait manuellement. À Dailymotion, nous sommes partis sur un seul dépôt, mais il aurait été possible de partir sur trois dépôts :
- un pour les miroirs de distributions,
- un pour les paquets maisons,
- un pour les miroirs de dépôts tiers.
Voici ce que nous allons mettre en place :
Mise en place#
La première étape est de créer un utilisateur pour travailler sur les dépôts :
$ adduser --system --disabled-password --disabled-login \ > --home /srv/packages \ > --group reprepro
Toutes les opérations qui suivent doivent utiliser exclusivement cet utilisateur. Chaque dépôt aura son propre répertoire dans lequel on trouvera les sous-répertoires suivants :
conf/
qui contient les fichiers de configuration,gpg/
qui contient les fichiers permettant de signer et authentifier les dépôts avec GPG1,logs/
qui contient les journaux,www/
qui contient les fichiers du dépôt à rendre visible par un quelconque server web.
Voici le contenu de conf/options
:
outdir +b/www logdir +b/logs gnupghome +b/gpg
Créons la clé GPG pour signer le dépôt :
$ GNUPGHOME=gpg gpg --gen-key Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 10y Key expires at mer. 08 nov. 2023 22:30:58 CET Is this correct? (y/N) y Real name: Dailymotion Archive Automatic Signing Key Email address: the-it-operations@dailymotion.com Comment: […]
Un mot de passe vide permet à reprepro de tourner sans intervention de l’utilisateur (notamment pour les mises à jour nocturnes). La clé publique devra être distribuée pour permettre à APT de vérifier les signatures de l’archive. Une façon commode de faire est de la placer dans un paquet.
Miroir local d’une distribution officielle#
Commençons par mettre en place un miroir pour Ubuntu Precise. Nous avons besoin de faire deux choses :
- Configurer une nouvelle distribution dans le fichier
conf/distributions
. - Configurer les sources dans le fichier
conf/updates
.
Ajoutons ce bloc dans conf/distributions
:
# Ubuntu Precise Origin: Ubuntu Label: Ubuntu Suite: precise Version: 12.04 Codename: precise Architectures: i386 amd64 Components: main restricted universe multiverse UDebComponents: main restricted universe multiverse Description: Ubuntu Precise 12.04 (with updates and security) Contents: .gz .bz2 UDebIndices: Packages Release . .gz Tracking: minimal Update: - ubuntu-precise ubuntu-precise-updates ubuntu-precise-security SignWith: yes
Il définit la distribution precise
dans notre dépôt. Elle contient
quatre composants : main
, restricted
, universe
et multiverse
(comme la distribution présente dans les dépôts officiels).
La ligne Update
commence par un tiret. Cela signifie que reprepro
va marquer tous les paquets comme à effacer avant d’appliquer les
mises à jour indiquées. Les paquets supprimés de la distribution
officielle ne seront donc pas conservés dans notre miroir. Dans
conf/updates
, nous définissons les sources :
# Ubuntu Precise Name: ubuntu-precise Method: http://fr.archive.ubuntu.com/ubuntu Fallback: http://de.archive.ubuntu.com/ubuntu Suite: precise Components: main main multiverse restricted universe UDebComponents: main restricted universe multiverse Architectures: amd64 i386 VerifyRelease: 437D05B5 GetInRelease: no # Ubuntu Precise Updates Name: ubuntu-precise-updates Method: http://fr.archive.ubuntu.com/ubuntu Fallback: http://de.archive.ubuntu.com/ubuntu Suite: precise-updates Components: main restricted universe multiverse UDebComponents: main restricted universe multiverse Architectures: amd64 i386 VerifyRelease: 437D05B5 GetInRelease: no # Ubuntu Precise Security Name: ubuntu-precise-security Method: http://fr.archive.ubuntu.com/ubuntu Fallback: http://de.archive.ubuntu.com/ubuntu Suite: precise-security Components: main restricted universe multiverse UDebComponents: main restricted universe multiverse Architectures: amd64 i386 VerifyRelease: 437D05B5 GetInRelease: no
Les lignes VerifyRelease
indiquent les empreintes des clefs GPG à
utiliser pour vérifier la signature des dépôts distants. Il faut
importer la clé en question dans l’anneau local :
$ gpg --keyring /usr/share/keyrings/ubuntu-archive-keyring.gpg \ > --export 437D05B5 | GNUPGHOME=gpg gpg --import
Un autre point important est le fait que nous avons fusionné trois
distributions (precise
, precise-updates
et precise-security
)
dans une seule distribution (precise
) dans notre dépôt local. Cela
peut provoquer des difficultés avec les outils, tels que le Debian
Installer2, qui s’attendent à trouver les trois
distributions classiques.
Il est ensuite possible de lancer reprepro pour mettre à jour le miroir :
$ reprepro update
Cela prend un certain temps la première fois. reprepro n’est pas la solution la plus efficace pour mettre en place un miroir, mais sa prise en main est simple et il est particulièrement fiable.
Dépôt maison#
Passons au dépôt pour les paquets maisons. Pour chaque distribution
officielle (telle que precise
), nous mettons en place deux
distributions :
precise-staging
contient les paquets en cours de test.precise-prod
contient les paquets testés issus deprecise-staging
.
Dans cette organisation, les paquets sont introduits dans
precise-staging
où ils peuvent être testés sur quelques serveurs
avant d’être copiés dans precise-prod
pour être disponible sur
l’ensemble de la plateforme. La déclaration dans conf/distributions
se fait ainsi :
# Dailymotion Precise packages (staging) Origin: Dailymotion # ❸ Label: dm-staging # ❸ Suite: precise-staging Codename: precise-staging Architectures: i386 amd64 source Components: main role/dns role/database role/web # ❶ Description: Dailymotion Precise staging repository Contents: .gz .bz2 Tracking: keep SignWith: yes NotAutomatic: yes # ❷ Log: packages.dm-precise-staging.log --type=dsc email-changes # Dailymotion Precise packages (prod) Origin: Dailymotion # ❸ Label: dm-prod # ❸ Suite: precise-prod Codename: precise-prod Architectures: i386 amd64 source Components: main role/dns role/database role/web # ❶ Description: Dailymotion Precise prod repository Contents: .gz .bz2 Tracking: keep SignWith: yes Log: packages.dm-precise-prod.log
Notez d’abord l’utilisation de plusieurs composants (en ❶) :
main
contiendra les paquets génériques. Un paquet placé dansmain
doit pouvoir être utilisé sur n’importe quel serveur.role/*
sont des composants dédiés à un sous-ensemble de la plateforme. Par exemple, dansrole/dns
, on trouvera des versions modifiées de BIND.
La distribution de test utilise le drapeau NotAutomatic
(en ❷) qui
indique au gestionnaire de paquets de ne pas installer ces paquets à
moins d’une requête expresse de l’utilisateur. Juste au-dessous, quand
un nouveau fichier dsc
est reçu, le script
email-changes
est exécuté. Il doit se trouver dans
le répertoire conf/
.
Les lignes Origin
et Label
(en ❸) sont particulièrement importants
car elles seront utilisées pour déterminer la politique d’installation
des paquets. Prenons ce fichier /etc/apt/sources.list
:
# Ubuntu packages deb http://packages.dm.gg/dailymotion precise main restricted universe multiverse # Dailymotion packages deb http://packages.dm.gg/dailymotion precise-prod main role/dns deb http://packages.dm.gg/dailymotion precise-staging main role/dns
Tous les serveurs peuvent utiliser la distribution
precise-staging
. Il est essentiel de ne pas installer par erreur des
paquets de cette distribution. Le drapeau NotAutomatic
est une
première sécurité. Nous y ajoutons ce fichier /etc/apt/preferences
:
Explanation: Dailymotion packages of a specific component should be more preferred Package: * Pin: release o=Dailymotion, l=dm-prod, c=role/* Pin-Priority: 950 Explanation: Dailymotion packages should be preferred Package: * Pin: release o=Dailymotion, l=dm-prod Pin-Priority: 900 Explanation: staging should never be preferred Package: * Pin: release o=Dailymotion, l=dm-staging Pin-Priority: -100
Par défaut, les paquets ont une priorité de 500. En utilisant une
priorité de -100 pour les paquets en provenance de la distribution de
test, nous nous assurons qu’ils ne peuvent pas être installés du
tout. C’est une contrainte plus forte que l’utilisation de
NotAutomatic
qui place la priorité à 1. Nous favorisons les paquets
se trouvant dans le dépôt maison par rapport aux paquets officiels en
leur affectant une priorité de 900 (voire 950 pour les paquets qui se
trouvent dans un composant type rôle).
La section “How APT Interprets Priorities” de la page de manuel
apt_preferences(5)
donne plus de détails. Il faut
garder en tête que les versions ne sont utilisées qu’à priorité
égale. La commande apt-cache policy
permet de vérifier que tout
fonctionne comme attendu :
$ apt-cache policy php5-memcache Installed: 3.0.8-1~precise2~dm1 Candidate: 3.0.8-1~precise2~dm1 Version table: *** 3.0.8-1~precise2~dm1 0 950 http://packages.dm.gg/dailymotion/ precise-prod/role/web amd64 Packages 100 /var/lib/dpkg/status 3.0.8-1~precise1~dm4 0 900 http://packages.dm.gg/dailymotion/ precise-prod/main amd64 Packages -100 http://packages.dm.gg/dailymotion/ precise-staging/main amd64 Packages 3.0.6-1 0 500 http://packages.dm.gg/dailymotion/ precise/universe amd64 Packages
Pour installer un paquet en provenance de la distribution de test, il
suffit d’invoquer apt-get
avec l’option -t precise-staging
qui
augmente la priorité de cette distribution à 990.
Une fois le paquet testé sur quelques serveurs, il est possible de le copier vers la distribution de production :
$ reprepro -C main copysrc precise-prod precise-staging wackadoodle
Miroir local de dépôts tiers#
Parfois, plutôt que de reconstruire un paquet, il est préférable de le prendre directement sur un dépôt tiers. Un exemple courant est les dépôts mis en place par les constructeurs. Comme pour la mise en place d’un miroir d’une distribution officielle, il y a deux étapes : définition de la distribution et déclaration des sources.
Chaque miroir va se trouver dans les mêmes distributions que nos paquets maisons mais ils iront dans un composant dédié. Cela nous permet d’utiliser la même organisation que pour les paquets locaux : ils apparaîtront dans la distribution de test avant d’être manuellement copiés, après validation, dans la distribution de production.
La première étape consiste à àjouter le composant et la ligne Update
appropriée dans le fichier conf/distributions
:
Origin: Dailymotion Label: dm-staging Suite: precise-staging Components: main role/dns role/database role/web vendor/hp Update: hp # […] Origin: Dailymotion Label: dm-prod Suite: precise-prod Components: main role/dns role/database role/web vendor/hp # […]
Le composant vendor/hp
a été ajouté aux deux distributions mais
seule la distribution de test a une ligne Update
. La distribution de
production obtiendra les paquets par copie manuelle.
La source des paquets est déclarée dans le fichier conf/updates
:
# HP repository Name: hp Method: http://downloads.linux.hp.com/SDR/downloads/ManagementComponentPack/ Suite: precise/current Components: non-free>vendor/hp Architectures: i386 amd64 VerifyRelease: 2689B887 GetInRelease: no
N’oubliez pas de rajouter la clé GPG correspondante dans l’anneau
local. À noter une fonctionnalité particulièrement intéressante de
reprepro qui permet de copier le composant non-free
dans le
composant vendor/hp
.
Construction des paquets Debian#
La configuration de reprepro est désormais terminée. Comment construire les paquets à placer dans la distribution de test ?
Selon le temps que vous souhaitez accorder à cette activité, il y a plusieurs possibilités :
-
Construire un paquet source en ajoutant un répertoire
debian/
. C’est la façon classique. Il est possible de partir de zéro ou de prendre un paquet existant dans une distribution plus récente ou un rétroportage d’un dépôt non officiel. -
Utiliser un outil qui va créer un paquet binaire à partir d’un répertoire, tel que fpm. Un tel outil va minimiser le boulot à effectuer pour construire un paquet et peut même empaqueter automatiquement certains types de logiciels.
Il n’y a pas de solution universelle. La première approche est plus chronophage mais dispose des avantages suivants :
-
Les sources restent disponibles dans le dépôt. Si vous avez besoin de reconstruire un paquet en urgence pour corriger un problème, il n’est pas nécessaire de partir a la recherche des sources qui peuvent être temporairement indisponibles. Bien sûr, cela n’est valable que pour les paquets qui ne téléchargent pas les dépendances depuis Internet.
-
La recette de construction est conservée3 dans le dépôt. Si quelqu’un active telle option et reconstruit le paquet, cette option ne sera perdue lorsqu’un autre personne reconstruira le paquet. Ces changements sont documentés dans le fichier
debian/changelog
. De plus, un système de gestion des versions peut être utilisé pour garder une trace précise des changements liés à l’empaquetage. -
Le paquet obtenu peut ensuite être proposé à l’inclusion dans Debian. Cela rendra service à de nombreuses autres personnes.
Mise à jour (10.2017)
Je présente une approche alternative pour créer des paquets Debian sans trop d’effort dans « Petit traité empirique de l’empaquetage Debian ».
Compilation#
pbuilder est utilisé pour la compilation automatique des
paquets4. Sa mise en place est relativement simple. Voici le
fichier pbuilderrc
utilisé :
DISTRIBUTION=$DIST NAME="$DIST-$ARCH" MIRRORSITE=http://packages.dm.gg/dailymotion COMPONENTS=("main" "restricted" "universe" "multiverse") OTHERMIRROR="deb http://packages.dm.gg/dailymotion ${DIST}-staging main" HOOKDIR=/etc/pbuilder/hooks.d BASE=/var/cache/pbuilder/dailymotion BASETGZ=$BASE/$NAME/base.tgz BUILDRESULT=$BASE/$NAME/results/ APTCACHE=$BASE/$NAME/aptcache/ DEBBUILDOPTS="-sa" KEYRING="/usr/share/keyrings/dailymotion-archive.keyring.gpg" DEBOOTSTRAPOPTS=("--arch" "$ARCH" "--variant=buildd" "${DEBOOTSTRAPOPTS[@]}" "--keyring=$KEYRING") APTKEYRINGS=("$KEYRING") EXTRAPACKAGES=("dailymotion-archive-keyring")
pbuilder
doit être invoqué avec les variables d’environnement
DIST
, ARCH
et (optionellement) ROLE
. La mise en place de chaque
environnement s’effectue ainsi :
for ARCH in i386 amd64; do for DIST in precise; do export ARCH export DIST pbuilder --create done done
Concernant les rôles, un crochet de type D
permet d’ajouter les
sources appropriées avant la compilation :
#!/bin/bash [ -z "$ROLE" ] || { cat >> /etc/apt/sources.list <<EOF deb http://packages.dm.gg/dailymotion ${DIST}-staging role/${ROLE} EOF } apt-get update
Un crochet de type E
permet de s’assurer que les paquets de la
distribution de test sont prioritairement utilisés pour la
construction :
#!/bin/bash cat > /etc/apt/preferences <<EOF Explanation: Dailymotion packages are of higher priority Package: * Pin: release o=Dailymotion Pin-Priority: 900 EOF
Enfin, un crochet de type C
permet d’obtenir un shell en cas
d’erreur, ce qui est pratique pour corriger un problème :
#!/bin/bash apt-get install -y --force-yes vim less cd /tmp/buildd/*/debian/.. /bin/bash < /dev/tty > /dev/tty 2> /dev/tty
Une compilation peut ensuite être lancée avec la commande :
$ ARCH=amd64 DIST=precise ROLE=web pbuilder \ > --build somepackage.dsc
Numérotation des versions#
Afin d’éviter des règles trop complexes pour les versions, tout paquet
est traité comme étant un rétroportage. Le schéma utilisé est le
suivant : X-Y~preciseZ+dmW
.
-
X
est la version amont5. -
Y
est la version Debian. S’il n’y a pas de version Debian, mettre 0. -
Z
est la version du backport dans Ubuntu. S’il n’existe pas, mettre 0. -
W
est notre version du paquet. Il est incrémenté à chaque changement dans le paquet. C’est le seul numéro que nous contrôlons. Tous les autres dépendent d’une entité en amont.
Supposons que l’on désire rétroporter le paquet wackadoodle
. Il est
disponible dans une Ubuntu plus récente en version 1.4-3
. La
première version du paquet aura pour version
1.4-3~precise0+dm1
. Après un changement dans le fichier
debian/rules
, nous obtenons la version 1.4-3~precise0+dm2
. En
amont, une version 1.5
devient disponible. Elle n’est disponible ni
dans Ubuntu, ni dans Debian. Le numéro de version du paquet sera alors
1.5-0~precise0+dm1
.
Quelques semaines plus tard, le paquet arrive chez Ubuntu dans la
version 1.5-3ubuntu1
. Vous y appliquez des changements pour obtenir
la version 1.5-3ubuntu1~precise0+dm1
.
Une convention compatible avec les pratiques de Debian concernant les
rétroportages est : X-Y~bpo70+Z~dm+W
.
Envoi#
Pour intégrer un paquet dans le dépôt, les étapes classiques sont les suivantes :
- Le paquet source est placé dans un répertoire
incoming/
. - reprepro remarque le paquet source, vérifie sa validité (signature, distribution) et le place dans l’archive.
- Le système de compilation remarque un nouveau paquet source à construire et lance la compilation de celui-ci.
- Une fois les paquets binaires construits, ils sont également
placés dans le répertoire
incoming/
. - reprepro détecte les paquets binaires et les intègre dans l’archive.
Cette façon de faire a le désavantage d’être difficile à suivre pour l’utilisateur. Une alternative est de concevoir un script de construction exécutant chaque tâche de manière synchrone et permettant ainsi à l’utilisateur de suivre son terminal le bon déroulement des opérations. Ce script s’occupe également d’inclure les paquets finaux dans l’archive :
$ reprepro -C main include precise-staging \ > wackadoodle_1.4-3~precise0+dm4_amd64.changes
Voilà !
-
Il est possible d’apprendre à l’installeur Debian de travailler avec un tel dépôt en utilisant un fichier de configuration approprié. ↩︎
-
fpm-cookery est un outil particulièrement pratique pour fpm, dans la même veine que Homebrew ou que l’arbre de ports des BSD. Il peut être utilisé dans une optique similaire. ↩︎
-
sbuild est une alternative qui est aussi l’outil utilisé officiellement par Ubuntu et Debian. Historiquement, pbuilder était plus orienté vers les besoins des développeurs. ↩︎
-
Pour un extrait de dépôt Git, le numéro de version amont utilisé ressemble à
1.4-git20130905+1-ae42dc1
ce qui correspond à un extrait situé après la version 1.4 (utiliser 0.0 s’il n’y a jamais eu de publication) à la date donnée. Le chiffre qui suit la date peut être incrémenté si plusieurs extraits sont utilisés dans la même journée. Enfin, le condensat à la fin permet de récupérer l’extrait exact. ↩︎