Gestion des dépendances

Ceci est un résumé de l’état des réflexions sur le sujet depuis l’aube des temps nasgaïens :p

Etat des lieux

définition : dépendance vis-à-vis d’une librairie (bibliothèque) dynamique ou statique. En général, la dépendance à une librairie dynamique est de type double :

  • lors de la compilation (cas, par exemple, des librairies statiques): liaison du binaire ou librairie
  • lors de l’exécution : le binaire ou la librairie demande le chargement de la librairie liée Pour les librairies statiques,

Une fois compilé, le binaire dépendra des librairies spécifiées. Notre format a l’avantage d’embarquer dans tout binaire la partie nbuild., il faut ajouter un systeme de classement des dépendances clair.

Types de dépendances :

  1. les bibliothèques dynamiques, on trouve facilement avec ldd

ldd cherche le paquet qui fournit la bibliothèque dans un dossier listé dans $LD_LIBRARY_PATH

  1. les fichiers de ressources
  2. les bibliothèques dynamiques qu’on ouvre avec dlopen
  3. les bibliothèques des langages de script (comme 2 et 3)

Pour 2-3-4 certains langages de script (grep ‘import’ *.py) peuvent être utilisés. Garder la possibilité de faire des plugins permetant de découvrir des dépendances ... mais le mainteneur du paquet doit aussi vérifier que toutes les dépendances sont bien présentes. et doit pouvoir en ajouter si besoin est.

Après, quel type de dépendances peut on avoir ?

  1. une dépendance sur des fichiers

il faudrait avoir la liste de TOUS les fichiers fournis par TOUS les paquets pour pouvoir gérer les dépendances, cette liste doit exister car l’utilisateur doit pouvoir rechercher un paquet en fonction du fichier qu’il installe

  1. une dépendance sur des noms de ressources
  2. une dépendance sur des noms de paquets + versions

toute la flexibilité disparaît

L’objectif est de trouver un compromis entre un système de dépendances sur des fichiers et un système de dépendances sur des paquets.

ncooker ne devrait pas gérer les dépendances ldd en dur mais avec des plugins ajouter la gestion de dépendances “humaines” (non gérées par ldd)

Proposition : un outil qui ldd et donne une liste des deps brute, et le nbuildeur tient compte à la fois des infos qu’il a et de celles-ci pour les ecrire dans le fichier depends

Proposition : ajouter des fonctions, appellables depuis le fichier “build”, permettant d’assigner un niveau à une dépendance

Proposition : “md5sum”iser à la fin de “make install”

Dans chaque nbuild peut être inclus un fichier hdepends contenant des lignes telles que : Ncooker regarde si prog-2.2.2 est bien installé, dans le cas contraire il signale son absence.

Le nbuildeur devra renseigner (ou pas) ce fichier manuellement. Par défaut la dépendance est supposée >= à celle indiquée dans le fichier hdepends. Pour avoir une dep strictement supérieure, incrémenter de 1 sa version. Une option de permettra à l’utilisateur de s’affranchier de la gestion des dépendances.

Si l’utilisateur veut ignorer les dépendances, il doit pouvoir le faire.

Solution en cours de débat

Deux parties : les dépendances dans le format de paquet et la gestion des dépendances par Ncooker.

La question est de savoir si on veut un format de nbuild limité à deux fichiers (”infos” et “build”) ou un format de nbuild composé d’une multitude de fichiers (”infos”, “files”, “builddeps”, “basicdeps”, “build” et d’autres encore). Dans le premier cas, on centralise toutes les informations dans un seul et unique fichier (”infos”) mais la lecture des informations est rendue plus complexe. Dans le deuxième cas, on sépare les différents types d’information mais cela nécessite d’avoir autant de parsers qu’il y a de formats.

Format du paquet

Format du fichier de dépendance

L’idée est d’inclure dans les paquets, zéro, un ou plusieurs fichiers de dépendances. Chaque ligne de ces fichiers représenteraient une dépendance. Une ligne pourrait avoir l’un des trois formats suivants : <chemin de fichier> <chemin de fichier> (<nom de paquet>) <chemin de fichier> (<nom de paquet> <operateur> <version>)

“chemin du fichier” est le chemin (absolu ou relatif) d’un fichier dont dépend le paquet. Par exemple, si un paquet dépend de l’utilitaire “cdrecord”, le chemin de fichier pourra être “bin/cdrecord”. Si un paquet dépend de la librairie “glib 2”, le chemin de fichier pourra être “lib/libglib-2.0.so.0”. Si un paquet dépend d’un fichier ressource dont le chemin est a posteriori fixé, un chemin absolu est alors nécessaire.

“nom de paquet” et “version de pquet” sont le nom et la version d’un paquet Nasgaïa.

“operateur” est soit “⇐“, soit “=”, soit “>=”. Il permet de spécifier la version minimale, exacte ou maximale d’un paquet dépendant.

Tester les opérateurs relationnels ⇐ et >=, le gros cas tordu consiste à comparer deux versions du genre “1.2” et “1.12”. Une comparaison directe arrivera à la conclusion que “1.12” est inférieure à “1.2” alors que 2 est bien inférieur à 12. Pour résoudre ce problème, l’on peut couper les chaînes en séparant les nombres et le reste :

1 . 2

1 . 12

La comparaison de chaque nombre ou chaque chaîne quelconque entre eux détectera que 2 est bien inférieur à 12 et on pourra conclure que “1.2” est inférieur à “1.12”.

Fichier(s) de dépendances

Les fichiers de dépendance seraient au nombre de trois : - “builddeps” (fichier des dépendances de construction d’un paquet) - “basicdeps” (fichier des dépendances d’exécution résumées) - “fulldeps” (fichiers des dépendances d’exécution complètes)

Un paquet Nbuild contiendrait les fichiers “builddeps” et “basicdeps”. Ces dépendances seraient vérifiées lors de la construction d’un paquet NBA. Un paquet NBA contiendrait les trois fichiers mais seules les dépendances du fichier “fulldeps” seraient vérifiées lors de l’installation du NBA. Les deux autres fichiers ne seraient utilisés que lors de l’extraction d’un paquet Nbuild à partir du paquet NBA et lors de la reconstruction d’un paquet NBA à partir du paquet NBA.

Spécifier les dépendances dans le fichier “infos” est une solution qui présente des avantages et des inconvénients. Si les informations “dépendances” sont éclatées, en fichiers distincts, on perd une bonne partie de l’intérêt “centralisateur” de xml, tout en gardant ses inconvenients. A ce moment là, une syntaxe plus épurée de type yaml (http://www.yaml.org/) pourrait être utilisée. En l’état actuel des choses, le fichier “infos” est modifié par Ncooker pour y ajouter des informations calculées automatiquement (le nom du Nbuildeur, les sommes MD5, ... ). Pourquoi ne pas en profiter pour scinder les valeurs en deux fichiers. Le premier est ce que le nbuilder écrit, le deuxième ce que Ncooker écrit.

Néanmoins : - il semble plus judicieux de séparer en deux fichiers ce qui est créé par le nbuilder (saisie) de ce qui est généré automatiquement (travail de Ncooker) - il sera bien plus facile à Ncooker d’aller chercher les infos de dépendances dans ce format de fichier simple et à part, que de lire des balises.

Espace dans le nom du fichier : mettre des guillemets simples. Si c’est bash qui récupère la valeur dans une variable, les guillemets seront interprétés pour protéger le contenu. Mieux vaut mettre des guilemets simples (contenu non interprété) que des guilemets doubles.

Ncooker

Où comment le Nbuildeur, l’utilisateur et Ncooker pourraient gérer les dépendances ...

Lors du développement d’un paquet Nbuild, le Nbuildeur créerait d’abord “à la main” les deux fichiers “builddeps” et “basicdeps”.

Pour la génération d’un nbuild minimal, ce sera bien que Ncooker assiste le nbuildeur dans la création de ces fichiers, Ncooker pourrait générer les dépendances telles qu’il les voit.

Pour pouvoir faire un ldd sur un binaire, il faut déjà que ce binaire existe. Or, si un nbuildeur est en train de créer un paquet, c’est que ce binaire n’est pas encore installé sur son système... Le Nbuilder est donc contraint de déterminer les dépendances “a priori”. Il devra utiliser la documentation du projet (fichiers “README”, “INSTALL”), le site web du projet, la page freshmeat du projet et... sa connaissance. ;) Bon, maintenant, si le nbuildeur souhaite complèter le fichier “basicdeps”, il aura toujours la possibilité de générer une première fois le paquet NBA, de consulter le fichier “fulldeps” généré et de modifier le paquet Nbuild en conséquence.

Voici quelques exemples :

- si la construction du paquet dépend d’un compilateur C, le Nbuildeur pourra ajouter la ligne suivante dans le fichier “builddeps” : bin/cc Autre idée : mécanisme permettant de retrouver les binaires à partir du PATH. Mais il peut arriver que l’utilisateur qui installe le paquet NBA (root) n’ai pas le même PATH que l’utilisateur qui va utiliser le paquet. Dans ce cas, la dépendance ne pourra pas être résolue lors de l’installation du paquet NBA. La solution la plus égalitaire semble être de rechercher le chemin du fichier dans la base de données Ncooker, quelque soit le type du fichier.

- si la construction d’un paquet dépend du compilateur gcc, le Nbuildeur pourra ajouter la ligne suivante dans le fichier “builddeps” : bin/gcc

- si la construction d’un paquet dépend du compilateur gcc dans sa version 4, le Nbuildeur pourra ajouter la ligne suivante dans le fichier “builddeps” : bin/gcc (gcc >= 4.0)

- si l’installation d’un paquet dépend de la bibliothèque “pango” dans sa version 1.3.2 minimale, le Nbuildeur pourra ajouter la ligne suivante dans le fichier “basicdeps” : lib/libpango-1.0.so.0 (pango >= 1.3.2) De même que pour les binaires, un moyen de spécifier les répertoires de bibliothèques en cherchant dans une variable propre à Ncooker qui s’appuie sur LD_LIBRARY_PATH.

Avec une base de donnée à jour, on peut utiliser locate. Et comme updatedb est lent, Ncooker pourrait la modifier pour ajouter les paquets qu’il installe au lieu de la vider et la reconstruire entièrement avec updatedb. Nous aurions même les fichiers installés par l’utilisateur sans passer par Ncooker (les make install dans /usr/local). Pour ce qui est de la longueur du updatedb, rlocate ( http://sourceforge.net/projects/rlocate/ ) permet de mettre celle-ci à jour en temps réel à chaque fois qu’une fichier est créé, supprimé ou renommé. Cette solution impose d’avoir le module en route en permanence.

Il n’y a pas de solution miracle mais que la solution la plus égalitaire serait de rechercher le chemin du fichier dans la base de données Ncooker, quelque soit le type du fichier. Une (ou des) variable de recherche pour Ncooker, qui pourraient être basées sur les variables existantes.

- si l’installation d’un paquet dépend d’un fichier “background.jpeg” attendu dans le répertoire “/usr/share/lib”, le Nbuildeur pourra ajouter la ligne suivante dans le fichier “basicdeps” : /usr/share/lib/background.jpeg

Le but n’est peut-être pas d’être exhaustif (cela est impossible dans l’absolu) mais de donner la liste de fichiers “clé” dépendants (ainsi que d’éventuels paquets). Le nbuildeur pourra, pour cela, utiliser la documentation du projet pour lequel il est en train de faire le paquet (fichiers “README”, “INSTALL” et autres). Par exemple, si on a besoin de gcc, il suffit de marcher un dépendance sur le binaire gcc et non sur la totalité des programmes nécessaires (cpp, ld, etc..) car ceux-là sont eux-même inclus dans gcc, ou une dépendance de ce dernier.

Dès qu’il y a possibilité de modifier un chemin (soit côté paquet qui définit le chemin, soit côté paquet qui a une dépendance dessus), il ne faut pas de chemin absolu. Si cela ne peut pas être modifié (exemple bidon, /etc/passwd), il faudra bien mettre le chemin absolu. Le principe général est qu’il est préférable d’utiliser les chemins relatifs.

Construction du paquet

Le nbuildeur fera ensuite appel à la commande “Ncooker build”. Ncooker contrôlera d’abord la syntaxe des deux fichiers de dépendances puis vérifiera les dépendances une par une de la façon suivante :

- si le fichier n’existe pas sur le système, Ncooker signalera la dépendance manquante. Si un paquet est précisé, Ncooker indiquera le paquet (à titre informatif). - si le fichier existe sur le système mais que le paquet éventuellement précisé n’est pas référencé sur le système, Ncooker indiquera que le paquet est manquant mais que le fichier existe. - si le fichier existe sur le système, que le paquet est installé sur le système mais que la version du paquet éventuellement précisée ne correspond pas à la version présente sur le système, Ncooker indiquera la version du paquet attendu et la version du paquet présent sur le système. - si la dépendance est résolue, Ncooker passera à la dépendance suivante en indiquant ok.

Une option permettra de faire en sorte que Ncooker ignore les dépendances. On peut aussi imaginer une option permettant d’ignorer les contrôles sur les paquets et les versions des paquets.

Lorsque la commande “Ncooker build” aura construit les fichiers du paquet NBA, elle pourra générer automatiquement les dépendances complètes (fichier “fulldeps”). Pour cela, elle partira du fichier “basicdeps”. Elle essaiera ensuite de compléter cette liste de fichiers en détectant les dépendances (ldd et autres). Pour chaque fichier, elle indiquera le nom du paquet dans lequel le fichier est présent (sans version) à titre informatif.

Le fichier “fulldeps” contiendra donc la liste la plus complète possible de tous les fichiers dont dépend le paquet, y compris les fichiers dépendants engendrés par le positionnement d’options de construction particulières par l’utilisateur. Les fichiers “builddeps” et “basicdeps” seront copiés “tels quels” dans le paquet NBA.

Une commande “Ncooker unpack” peut désarchive le nbuild dans un répertoire en ne gardant que les informations à modifier manuellement par le nbuildeur.

Installation d'un NBA

Lorsque l’utilisateur souhaite installer un paquet NBA, il appelle la commande “Ncooker install” qui vérifiera les dépendances spécifiées dans le fichier “fulldeps”. Les vérifications se feront de la même façon que décrite ci-dessus pour la commande “Ncooker build”.

 
ncookeridea.txt · Dernière modification: 01/05/2006 14:28 par fraazz
 
Recent changes RSS feed Creative Commons License Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki