Dans cet article, je vais vous expliquer comment installer sur votre serveur un dépôt APT privé.
L’intérêt est de pouvoir publier un projet avec du code fermé car les PPA (que j’explique dans cet article) de launchpad.net sont utilisable que pour les projets open source.
Dans mon cas j’en ai besoin pour mon project Douane (que je présente dans cet article [Anglais]).
Principe de fonctionnement
Une fois que votre code source est prêt pour être empaqueté, à l’aide de la commande dput
vous enverrez sur votre serveur les fichiers de votre projet et ce dernier qui aura les services rebuildd et reprepro qui tourneront, va compiler votre projet puis génerer les paquets .deb
pour les différentes architectures que vous aurez configuré.
Finalement les personnes voulant utiliser votre projet n’auront plus qu’a ajouter votre serveur dans leur sources d’apt, importer votre clé GPG puis mettre à jour leur liste de paquet et installer votre projet.
Le dépôt
Nous allons commencer par mettre en place le dépôt APT et sa clé GPG sur votre serveur de facon à ce que vous puissiez appeler votre serveur, avec apt, depuis votre machine. Bon le dépôt sera vide mais au moins il fonctionnera :-)
Installation
L’application qui permet de mettre en place un dépôt APT est reprepro.
Une fois que vous êtes connecté à votre serveur:
1
2
sudo apt-get install reprepro
sudo mkdir -p /srv/reprepro/{conf,incoming,incomingtmp,bin}
Ceci va donc installer reprepro
et créer la structure dans laquelle votre serveur stockera les paquets.
Configuration
Maintenant nous allons configurer reprepro
.
conf/distributions
Il faut créer le fichier /srv/reprepro/conf/distributions
(en utilisant sudo
) et y décrire les différentes distributions supporté par le dépôt:
J’explique plus bas à quoi servent les lignes:
1
2
Log: logfile
--changes /srv/reprepro/bin/build_sources
conf/options
Nous allons aussi définir les options que nous voulons pour reprepro
en créant le fichier /srv/reprepro/conf/options
(en utilisant sudo
) avec ce contenu:
1
2
verbose
basedir .
conf/incoming
Afin que nous puissions utiliser la commande dput
pour envoyer nos projets il faut configurer une queue d’entrée pour les fichiers. Pour ce faire créez le fichier /srv/reprepro/conf/incoming
avec ce contenu:
Dans ce fichier vous devez spécifier les séries/versions que vous supportez. Dans mon exemple j’ai mis les versions precise quantal raring saucy d’Ubuntu.
Création d’une clé GPG
Afin d’éviter que quelqu’un publie des paquets en se faisant passer pour vous il faut créer une clé GPG qui sera utilisée pour signer les paquets .deb
.
Sur votre serveur:
1
2
sudo -i
gpg --gen-key
(Il est important d’exécuter gpg --gen-key
de cette facon, sinon la clé sera attribué à votre utilisateur et vous auriez l’erreur suivante l’or de l’envoie des paquets créé dans votre dépôt:
1
Could not find any key matching 'votre.clé@repo.votre-serveur.com'
Gardez les valeurs par défaut à chaque questions.
Seul les questions Real name: et Email address: sont importantes.
L’adresse email DOIT correspondre à celle que vous avez mis dans le fichier /srv/reprepro/conf/distributions
.
Cette adresse sera visible dans les paquets.
Pour le moment n’entrez pas de passphrase. Ce n’est pas top pour la sécurité, mais je n’ai pas encore réussi à avoir reprepro fonctionnant avec une clé GPG avec une passphrase…
Une fois terminé vous devriez avoir à la fin quelque chose comme ca:
1
2
3
4
pub 2048R/55B0A66B 2014-01-27
Key fingerprint = A335 3D06 888C 868A BE0C 9A93 2002 7088 44B9 A86B
uid Real name <adresse.email@votre-serveur.com>
sub 2048R/A47A9C27 2014-01-27
Il est important pour l’étape suivante que vous sachiez trouver l’ID de votre clé. Dans cet exemple l’ID est 55B0A66B. C’est la valeur apres le slash (/) de la première ligne.
Publication de la clé GPG
Lorsque les utilisateurs ajouterons votre serveur dans leur sources pour apt, il devront importer votre clé GPG (clé publique), donc il faut la mettre sur un serveur.
Sur votre serveur:
1
2
sudo gpg --keyserver keyserver.ubuntu.com --send-keys 55B0A66B
gpg: sending key 55B0A66B to hkp server keyserver.ubuntu.com
La clé est bien envoyée sur le serveur :-)
Nginx
Pour finir il faut configurer nginx (ou apache) pour donner un accès en HTTP à notre dépôt.
Créez le fichier de configuration avec ce contenu:
Puis redémarrez nginx.
Configurer apt pour utiliser votre serveur
Pour finir cette première partie, il ne reste plus qu’à configurer apt
sur votre machine pour accéder à votre dépôt (oui vide pour le moment).
1
2
sudo add-apt-repository http://repository.votre-serveur.com/
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 55B0A66B
Bien entendu vous remplacerez l’ID 55B0A66B par le votre ;-)
Maintenant si vous mettez à jour apt:
1
2
3
sudo apt-get update
[...]
W: Failed to fetch http://repository.votre-serveur.com/dists/saucy/main/binary-amd64/Packages 404 Not Found
Donc apt
a bien contacté votre serveur, mais celui-ci n’a pas de paquet a installer (Et donc pas de fichier Packages).
Mon premier paquet
Maintenant que notre dépôt est pret il faut le remplir! :-)
Ce que nous voulons c’est avoir un comportement proche des PPA de launchpad.net, c’est à dire envoyer les sources et que le serveur compile pour différentes distributions et architectures.
Nous allons pouvoir faire ceci grâce à rebuildd
.
Installation
Ici rien de compliqué. Sur votre serveur:
1
sudo apt-get install rebuildd
Configuration
Voici le cœur du sujet! :-)
/etc/default/rebuildd
Premièrement il faut authoriser l’exécution de rebuildd
.
Modifiez le fichier /etc/default/rebuildd
en changant ces paramètres:
1
2
3
4
5
START_REBUILDD=1
START_REBUILDD_HTTPD=1
PBUILDER_MIRROR=http://archive.ubuntu.com/ubuntu/
ARCHS="i386 amd64"
DISTS="precise quantal raring saucy"
START_REBUILDD authorise rebuildd
de démarrer et START_REBUILDD_HTTPD authorise de démarrer l’interface web (je vous montre le résultat plus bas).
PBUILDER_MIRROR indique ou chercher les versions d’Ubuntu. Ici j’utilise le dépôt principal d’Ubuntu.
Pour finir ARCHS indique que nous voulons complier des paquets 32 et 64 bits et DISTS permet de préciser pour quelles versions d’Ubuntu nous voulons faire des paquets.
Vous remarquerez que nous avons déjà indiqué cette liste dans la configuration de reprepro
. La raison est que rebuildd
et reprepro
sont deux applications différentes pouvant être utilisé indépendement.
(Peut-être une amélioration de cet article: Trouver un moyen de spécifier 1 seule fois les configurations identiques.)
/etc/pbuilderrc
Dans ce fichier nous allons définir une confguration qui sera utilisée par pbuilder
l’or de la création des environnements. Par exemple nous allons ajouter le support des dépôts univers et multivers d’Ubuntu.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
## Overrides /etc/pbuilderrc
# Default distribution
# DISTRIBUTION=saucy
COMPONENTS="main restricted universe multiverse"
# Repositories
MIRRORSITE=http://archive.ubuntu.com/ubuntu
#OTHERMIRROR="deb ${MIRRORSITE} ${DISTRIBUTION}-updates ${COMPONENTS}|deb ${MIRRORSITE} ${DISTRIBUTION}-security ${COMPONENTS}"
# For build results
BUILDRESULT=/var/cache/pbuilder/result
# Hooks for chroot environment
# HOOKDIR=/var/cache/pbuilder/hook.d
# Mount directories inside chroot environment
BINDMOUNTS=${BUILDRESULT}
# Bash prompt inside pbuilder
export debian_chroot="pbuild$$"
# For D70results hook
export LOCALREPO=${BUILDRESULT}
# Always include source package
DEBBUILDOPTS="-b"
Préparation des environnements de compilation
Pour pouvoir préparer des paquets pour différentes versions d’Ubuntu (et surtout différentes architectures), rebuildd
utilise pbuilder
.
Ce dernier créer des environments en créant un environnement émulant la version voulut.
rebuildd-init-build-system
Cette commande va créer les environnements définis grâce aux variables précédement définies dans /etc/default/rebuildd
: ARCHS et DISTS.
Il va faire la combinaisons des 2 et va donc créer un environment 32 bits et 64 bits pour la version precise d’Ubuntu et ainsi de suite.
Donc dans un terminal:
1
sudo rebuildd-init-build-system
(Cette commande prendra plus ou moins de temps, dépendant des variables ARCHS et DISTS).
Si vous utilisez Debian
Si vous êtes sous Debian et que vous désirez faire des paquets pour Ubuntu, vous devriez avoir une erreur indiquant que la clé GPG pour le dépôt d’Ubuntu est inconnu.
Un paquet (http://packages.debian.org/jessie/all/ubuntu-archive-keyring/download) pour une trés ancienne version de Debian existait mais il n’est plus disponible. :-(
Une solution est de télécharger et d’installer manuellement ce paquet:
1
2
3
cd /tmp
wget http://ftp.us.debian.org/debian/pool/main/u/ubuntu-keyring/ubuntu-archive-keyring_2012.05.19-1_all.deb
sudo dkpg -i ubuntu-archive-keyring_2012.05.19-1_all.deb
Si vous voulez supporter Ubuntu saucy
Dans ce cas rebuildd-init-build-system
va se terminer en erreur disant:
1
No such script: /usr/share/debootstrap/scripts/saucy
En jettant un oeil dans ce dossier on s’apercoit que par exemple le script raring est juste un lien vers le script gutsy. Faisons la même chose:
1
2
cd /usr/share/debootstrap/scripts/
sudo ln -s gutsy saucy
Puis relancer rebuildd-init-build-system
.
Initialiser rebuildd
Pour fonctionner, rebuildd
utilise une base de données.
Pour initialiser cette base de données il suffit de lancer la commande:
1
sudo rebuildd init
Déclanchement de fabrication des paquets
Plus haut je disais que j’expliquais les lignes:
1
2
Log: logfile
--changes /srv/reprepro/bin/build_sources
Et bien c’est ici :-D
Ce qu’elles veulent dire c’est que le script /srv/reprepro/bin/build_sources
sera exécuté dés qu’un fichier source sera ajouté ou supprimé du dépôt.
C’est exactement ce qu’il nous faut de facon à avoir un système entièrement automatique.
/srv/reprepro/bin/build_sources
Il nous faut donc créer ce script.
Son role est de créer un job rebuildd pour le fichier source ajouté. Voici un exemple de script:
Ne pas oublier:
1
sudo chmod +x /srv/reprepro/bin/build_sources
En gros le script créer le job rebuildd que si c’est un ajout et si le fichier est un fichier source (finissant par _source.changes).
Info: rebuildd travail avec un système de queue. Le script va ajouter une entrée dans la queue de rebuildd, mais si le serveur de rebuildd n’est pas démarré, rien ne se passera.
/etc/rebuildd/rebuilddrc
Avant de démarrer rebuildd il faut mettre à jour le fichier de configuration /etc/rebuildd/rebuilddrc
.
[build]
Premièrement il faut changer dists
en remettant les versions que vous supportez:
1
dists = precise quantal raring saucy
TODO: Expliquer cette ligne.
1
source_cmd = /srv/reprepro/bin/get_sources ${d} ${p} ${v}
Pour gérer la signature automatique de vos paquets avec la clé GPG du dépôt il nous faut un autre script:
1
post_build_cmd = /srv/reprepro/bin/upload_binaries ${d} ${p} ${v} ${a}
[mail]
Afin de recevoir les emails des fabrications de paquets:
1
mailto = votre-adresse.email@fournisseur.fr
/srv/reprepro/bin/get_sources
TODO: Expliquer cette ligne.
Voici un exemple de script qui …:
Ne pas oublier:
1
sudo chmod +x /srv/reprepro/bin/get_sources
/srv/reprepro/bin/upload_binaries
Voici un exemple de script qui utilise l’utilisateur debman pour signer le paquet:
Ne pas oublier:
1
sudo chmod +x /srv/reprepro/bin/upload_binaries
Démarrage des services rebuildd
Pour que les jobs rebuildd ajouté par le script build_sources
soient exécuté il faut démarrer les services rebuildd.
Tout d’abord démarrons rebuildd:
1
sudo service rebuildd start
Puis démarrons l’interface web de rebuildd:
1
sudo service rebuildd-httpd start
Vous pouvez d’or et déjà aller sur cette interface web en utilisant votre navigateur web préféré et en allans sur le port 9998.
Vous devriez obtenir ceci:
Envoyer mon premier paquet
Il est temps d’envoyer quelquechose à empaqueté!
Pour ce faire nous utiliserons la commande dput
.
Configuration
La configuration de dput
consiste en la création d’un fichier .dput.cf
sur votre machine de développement avec le contenu suivant:
1
2
3
4
5
6
7
8
9
10
11
[DEFAULT]
default_host_main = notspecified
[mon-serveur]
fqdn = repository.mon-serveur.com
login = ftpsecure
incoming = /incoming
method = ftp
hash = sha
allow_unsigned_uploads = 0
run_dinstall = 0
Pour suivre le principe de fonctionnement des PPA, j’utilise ici la methode ftp. Un compte ftpsecure avec des acces limité est utilisé.
Importer sa clé GPG
Lorsque vous exécutez la commande debuild -S -sa
vous signer avec votre clé GPG (sur votre machine de dévelopment cette fois) les fichiers.
Il faut donc que reprepro connaisse votre clé publique afin d’accepter uniquement les fichiers pour les clé qu’il connait (et rejeter tout autres envoie de n’importe qui).
Pour ce faire vous devez exporter votre clé public GPG et l’envoyer sur votre serveur depuis votre machine de développement:
1
2
gpg --armor --export votre-adresse-email > votre-adresse-email.asc
scp ./votre-adresse-email.asc root@votre-serveur:~/
Ensuite connectez-vous à votre serveur, la clé se trouve dans son dossier ‘home’ de root. Importez la:
1
2
sudo gpg --import /root/votre-adresse-email.asc
sudo rm /root/votre-adresse-email.asc
Installer et configurer le service ftp
Il faut maintenant que le service ftp tourne sur votre serveur:
1
2
sudo apt-get install vsftpd
sudo adduser --home /srv/reprepro/ ftpsecure
Entrez un mot de passe qui sera à fournir à chaque envoie.
Maintenant changons quelques options dans /etc/vsftpd.conf
:
1
2
3
4
5
6
7
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
nopriv_user=ftpsecure
chroot_local_user=YES
Et changez les droits de /srv/reprepro/
:
1
2
3
4
sudo chmod 750 -R /srv/reprepro/
sudo chmod 755 -R /srv/reprepro/incoming
sudo chown ftpsecure:ftpsecure /srv/reprepro/incoming
sudo chmod 755 /srv/reprepro/
De cette facon le dossier ‘home’ de l’utilisateur ftpsecure est /srv/reprepro/
mais il ne peux accéder que dans /srv/reprepro/incoming
.
Et un petit redémarrage de vsftp:
1
sudo service vsftpd restart
/etc/apt/sources.list
Ici nous allons mettre a jour le fichier /etc/apt/sources.list
de votre serveur avec les dépôts que vous supportez vers votre propre serveur.
Cela vous semble bisard ? Je vous rassure c’est normal ! :-) Allez, on s’accroche, car ca va pas être facile à comprendre.
Cette partie est importante car avant que pbuilder
se lance pour fabriquer votre paquet, le script /srv/reprepro/bin/get_sources
va être exécuté avec le paramètre -t <distribution ubuntu>
afin de récuperer tout le contenue de votre propre dépôt, et donc avoir le fichier .tar.gz
ainsi que \_source.changes
dans l’environnement de pbuidler.
Sans cette partie pbuilder
n’aurait rien a fabriquer.
Donc ajouter ces lignes pour chaque version d’Ubuntu que vous supportez:
1
2
3
# Sources for rebuildd
deb http://repository.mon-serveur.com saucy main
deb-src http://repository.mon-serveur.com saucy main
Donc selon l’exemple de cet article:
1
2
3
4
5
6
7
8
9
10
11
12
# Sources for rebuildd
deb http://repository.mon-serveur.com precise main
deb-src http://repository.mon-serveur.com precise main
deb http://repository.mon-serveur.com quantal main
deb-src http://repository.mon-serveur.com quantal main
deb http://repository.mon-serveur.com raring main
deb-src http://repository.mon-serveur.com raring main
deb http://repository.mon-serveur.com saucy main
deb-src http://repository.mon-serveur.com saucy main
Envoie
Dans le dossier de votre projet, apres avoir préparé le dossier debian/ et excécuté la commande debuild -S -sa
vous devriez avoir un fichier finissant par _source.changes.
1
2
3
4
5
6
7
8
dput mon-serveur ./helloworld_1.0.0-0ubuntu1~amd64~saucy1_source.changes
[...]
Uploading to mon-serveur (via ftp to repository.mon-serveur.com):
ftpsecure@repository.mon-serveur.com password:
Uploading helloworld_1.0.0-0ubuntu1~amd64~saucy1.dsc: done.
Uploading helloworld_1.0.0-0ubuntu1~amd64~saucy1.tar.gz: done.
Uploading helloworld_1.0.0-0ubuntu1~amd64~saucy1_source.changes: done.
Successfully uploaded packages.
Les fichiers seront copier dans votre dépôt, puis rappatrié pour pbuilder grâce a apt et pbuilder se lancera pour fabriquer votre paquet. Pour finir votre paquet sera copié dans votre dépôt et donc disponible.
Démarrage de la fabrication des paquets
Maintenant que les fichiers sont sur votre serveur, a la bonne place, il ne reste plus qu’a lancer la fabrication:
1
sudo reprepro -V -b /srv/reprepro processincoming incoming
Cette commande va copier les sources au bonne endroit pour pbuilder puis créer un job pour rebuildd afin de fabriquer les paquets. Une fois la commande terminé, si vous allez sur l’application web rebuildd vous verez le job:
Automatiser le démarrage
Pour éviter de devoir se connecter et lancer la commande a la main tout le temps, nous allons utiliser inotify (Module Linux pour écouter des évements du disque dur comme la création/modification/… de fichiers).
La solution que je vous propose est incron.
Tout d’abord installez le paquet sur votre serveur:
1
sudo apt-get install incron
Il faut autoriser l’utilisateur root en modifiant le fichier /etc/incron.allow
et en ajoutant root.
Puis le configurer:
1
sudo incrontab -e
Ceci vous ouvre un fichier a modifier. Ajoutez cette ligne:
Puis tappez :
et wq
pour sauvegarder et quitter.
Des lor, lorsque des fichiers seront ajouté dans le dossier /srv/reprepro/incoming
, le script reprepro_trigger.sh
sera exécuté.
Donc il faut créer le script avec sudo nano /usr/local/bin/reprepro_trigger.sh
:
Et ne pas oublier de le rendre exécutable:
1
sudo chmod +x /usr/local/bin/reprepro_trigger.sh