Café Guix, commandes guix time-machine
et guix describe
À l'occasion de ce Café
Guix, nous découvrirons les commandes guix time-machine
et guix describe
à
travers d'un cas d'utilisation pratique – la reproduction d'un environnement
logiciel créé avec la commande guix shell
. Après une brève mise en situation,
nous rappelerons quelques autres commandes et notions associées à Guix puis nous
expliquerons comment nous pouvons nous servir de guix time-machine
et guix
describe
dans le cadre du cas pratique abordé. Nous poursuivrons avec d'autres
exemples d'application de ces commandes et présenterons une utilisation plus
avancée de celles-ci. Enfin, nous verrons quelques suggestions de bonnes
pratiques d'utilisation au moyen d'une petite démonstration.
Café Guix
Le Café Guix est un évènement mensuel et informel d'échange autour du gestionnaire d'environnement logiciel GNU Guix [1]. Retrouvez plus d'informations, le programme des rencontres ainsi que les enregistrements et supports des sessions passées sur cette page.
Mise en situation
Nous sommes au printemps 2022. Je suis en pleine préparation de ma thèse de
doctorat dans le domaine du calcul haute-performance. Dans ce cadre-là, je
travaille sur une application d'algèbre linéaire basée sur la bibliothèque MUMPS
[2], [3]. Bien entendu, j'utilise Guix pour gérer mon
environnement logiciel composé de la chaîne de compilation du compilateur GCC
(paquet gcc-toolchain
), de la bibliothèque MUMPS (paquet mumps
) et d'un
shell de base (paquets bash
et coreutils
). Pour entrer dans mon
environnement logiciel et d'y ouvrir un shell, il me suffit de me servir de la
commande guix shell
[4] comme suit.
guix shell --container gcc-toolchain mumps bash coreutils -- bash
Revenons en 2024. Ajourd'hui, je voudrais reprendre mon projet. J'exécute donc
la même ligne de commande guix shell
afin de retrouver mon environnement
logiciel d'origine.
Obtiendrai-je exactement le même environnement ?
Deux années se sont écoulées depuis. Guix a évolué, les paquets ont été mis à jour. Dans ce cas, par exemple, la chaîne de compilation est passée de la version 11.2.0 à la 13.2.0 et la bibliothèque MUMPS est passée de 5.2.1 à 5.5.1.
En d'autres termes, l'environnement obtenu avec cette ligne de commande guix
shell
aujourd'hui ne sera pas tout à fait le même que celui obtenu au
printemps 2022.
Même s'il est possible de spécifier les versions des paquets demandés dans un
environnement logiciel créé avec guix shell
,
guix shell --container gcc-toolchain@11.2.0 mumps@5.2.1 bash coreutils -- bash
nous ne sommes pas sûr de retrouver exactement le même environnement. D'un côté,
pour la plupart des paquets, y compris pour mumps
, les versions anciennes
disparaissent avec l'arrivée de nouvelles versions. De l'autre côté, même si
tous les paquets demandés étaient encore disponibles en version de l'époque, il
faudrait qu'il en soit de même pour toutes leurs dépendances…
Dans un monde idéal, que me faudrait-il pour retrouver mon environnement ?
Quelques rappels
Dans Guix, les paquets logiciels sont mis à disposition à travers de ce que l'on appelle les canaux [7]. Guix lui-même ainsi que 28 026 autres paquets (au 27 mai 2024) sont disponibles depuis le canal officiel de Guix. Cependant, il existe de nombreux autres canaux dans la nature. Au fil du temps, l'offre de paquets dans ces canaux évolue. Les versions changent, de nouveaux paquets ou de nouvelles fonctionnalités de Guix apparaissent, d'autres disparaissent.
Sous le capot, les canaux sont en fait des dépôts git ce qui permet de retracer tout changement effectué à l'aide de son numéro de révision, autrement dit de son commit.
Figure 1: Les derniers commits dans le dépôt du canal officiel de Guix sur https://git.savannah.gnu.org/cgit/guix.git/.
Lorsqu'un utilisateur souhaite mettre à jour son installation locale de Guix, il
peut le faire à l'aide de la commande guix pull
[8]. Cette
dernière va télécharger les derniers changements, autrement dit les derniers
commits, des canaux utilisés. Dans la terminologie de Guix, cette action
aboutit à la création d'une nouvelle génération de Guix pour l'utilisateur en
question. Nous aurons encore l'occasion de revenir vers ce concept un peu plus
tard.
Revenons maintenant à la commande guix shell
. Lorsque nous faison appel à
cette dernière pour créer un environnement logiciel, celle-ci va consulter les
paquets disponibles dans notre génération de Guix actuelle et prendre leurs
versions par défaut. La plupart du temps, la version par défaut est également la
version la plus récente disponible dans le canal concerné. Dans notre exemple de
la section Mise en situation, la ligne de commande
guix shell --container gcc-toolchain mumps bash coreutils -- bash
effectuée au printemps 2022 a donné lieu à la sortie suivante.
/* * * This file is part of MUMPS 5.2.1, released * on Fri Jun 14 14:46:05 UTC 2019 * gcc (GCC) 11.2.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
À l'époque, nous avons donc obtenu un environnement avec le compilateur GCC en version 11.2.0 et la bibliothèque MUMPS en version 5.2.1. La même ligne de commande effectuée avec une génération de Guix datant du 22 mai 2024 crée un environnement avec GCC 13.2.0 et MUMPS 5.5.0.
/* * * This file is part of MUMPS 5.5.1, released * on Tue Jul 12 13:17:24 UTC 2022 * gcc (GCC) 13.2.0 Copyright (C) 2023 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
En effet, au printemps 2022, ma génération de Guix a été basée sur la révision
ee92b0fb7dfd8b55ea63254a59a1605fb870a44c
du canal officiel de Guix. Ma
génération de Guix actuelle est basée sur la révision
413ef75f89ac337f7ac3331a862c7c8cdc88aa64
.
Figure 2: Extrait du graphe de révisions (commits) du dépôt git du canal officiel de Guix.
guix time-machine
et guix describe
Pour que ma ligne de commande guix shell
donne aujourd'hui lieu à exactement
le même environnement logiciel qu'au printemps 2022, il nous faudrait pourvoir
remonter le temps et exécuter la commande guix shell
en utilisant la
génération de Guix de l'époque, c'est-à-dire celle basée sur la révision
ee92b0fb7dfd8b55ea63254a59a1605fb870a44c
du canal officiel de Guix.
Étant donné que les canaux sont des dépôt git, nous pouvons revenir en arrière,
en d'autres termes, faire une sorte de git checkout <bon-commit>
sur le canal
officiel de Guix. C'est ce que nous permet de faire la commande guix
time-machine
.
guix time-machine --no-channel-files \
--commit=<bon-commit> -- <commande guix>
Nous remarquerons que la machine à voyager dans le temps de Guix ne raisonne pas en termes de dates et heures, mais en termes de commits, tout comme un dépôt git. Lors de la construction d'un environnement logiciel avec Guix, il est donc très important de garder la trace des commits des canaux utilisés lors de sa création afin de pouvoir retrouver le même environnement plus tard ou sur une autre machine équipée de Guix.
Comment obtenir les informations sur mon installation Guix actuelle ?
La réponse à cette question est la commande guix describe
. Cette dernière
permet d'afficher les informations telles que les liens et les numéros de
commit des les canaux qui ont été utilisés pour créer la dernière génération
de Guix dans notre profil utilisateur avec la commande guix pull
(voir
Quelques rappels).
À titre d'exemple, voici la sortie de la commande guix describe
sur ma machine
personnelle.
Pokolenie 1 22. máj 2024 02:30:17 (súčasné) guix-hpc dd9eadb zdroj repozitára: https://gitlab.inria.fr/guix-hpc/guix-hpc.git vetva: master úprava: dd9eadb6bd5b73912812594251cb7135327f84c0 guix-science-nonfree 417f86b zdroj repozitára: https://github.com/guix-science/guix-science-nonfree.git vetva: master úprava: 417f86b4819bb45df671c3276216e57d2a427156 guix-past 921f845 zdroj repozitára: https://gitlab.inria.fr/guix-hpc/guix-past vetva: master úprava: 921f845dc0dec9f052dcda479a15e787f9fd5b0a guix-science f85279b zdroj repozitára: https://github.com/guix-science/guix-science.git vetva: master úprava: f85279b8aeac3cc3e6e2aec866841c722c5663fe guix 413ef75 zdroj repozitára: https://git.savannah.gnu.org/git/guix.git vetva: master úprava: 413ef75f89ac337f7ac3331a862c7c8cdc88aa64
Si je traduis, ma génération de Guix actuelle date du 22 mai 2024 et elle est constituée de 5 canaux au total dont le canal officiel de Guix listé en dernier lieu. Pour chacun des canaux utilisés, nous retrouvons ici l'adresse du dépôt git associé, la branche et le numéro de commit utilisés.
Encore une fois, en référence à l'exemple de la section Mise en situation,
ma génération de Guix actuelle est basée sur la révision
413ef75f89ac337f7ac3331a862c7c8cdc88aa64
du canal officiel de Guix alors qu'au
printemps 2022, elle était basée sur la révision
ee92b0fb7dfd8b55ea63254a59a1605fb870a44c
.
Et ce voyage dans le temps ?
Enfin de compte, si nous rassemblons tous les éléments de cette secion, pour
retrouver aujourd'hui mon environnement logiciel de l'époque, je vais remonter
le temps à l'aide de guix time-machine
en lui fournissant un repère temporel
exact, sous la forme d'un commit, obtenu grâce à guix describe
au printemps
2022, au moment de la construction initiale de mon environnement.
guix time-machine --no-channel-files \ --commit=ee92b0fb7dfd8b55ea63254a59a1605fb870a44c -- \ shell --container gcc-toolchain mumps bash coreutils -- bash
Discussion
Nous venons de voir qu'est-ce que les commandes guix describe
et guix
time-machine
nous permttent de faire à travers un cas d'utilisation pratique.
guix time-machine
, en principe utilisée de pair avec une autre commande de
Guix telle que guix shell
, nous autorise à exécuter cette dernière dans une
version antérieure de Guix. Il est à noter qu'ici le terme « antérieure » est
relatif à la dernière version de Guix disponible dans le canal officiel de Guix,
et non pas à la dernière génération de Guix dans notre profil utilisateur (voir
Quelques rappels). Autrement dit, si notre génération de Guix n'est pas basée sur le
dernier commit du canal officiel de Guix, la commande guix time-machine
peut
aussi nous amener dans le futur qui nous est encore inconnu localement.
La machine à voyager dans le temps de Guix n'utilise pas de dates et heures
comme repères temporels mais plutôt les numéros de commits des canaux utilisés
pour créer une génération de Guix donnée. C'est avec la commande guix describe
que nous pouvons nous informer sur les canaux actuellement utilisés par notre
génération de Guix afin de garder la trace d'un repère temporel pour plus tard
comme dans notre cas d'utilisation pratique.
D'autres cas d'utilisation
En plus du cas où nous aurions envie de reprendre un ancien travail plus tard,
le tandem guix time-machine
, guix describe
et guix shell
peut nous servir
dans d'autres situations.
Dans le cadre d'un projet à long terme, il est probable que notre environnement logiciel évolue régulièrement. Nous ajoutons de nouvelles fonctionnalités dans notre logiciel ou nous voulons profiter des derniers développements dans une bibliothèque que nous utilisons. Dans ce contexte, il peut s'avérer très utile de garder la trace des générations de Guix utilisées lors de la création de notre environnement et de pouvoir revenir en arrière, par exemple en cas de problème avec un environnement plus récent ou à des fins de comparaison entre deux versions de notre environnement.
Similairement au cas d'utilisation évoqué dans la section Mise en situation, même si l'environnement logiciel de notre projet na pas vocation à évoluer, nous pouvons avoir envie de nous assurer que nous utilisons toujours le même environnement pour travailler sur le projet afin d'éviter d'éventuels dysfonctionnements ou problèmes de compatibilité liés à une mise à jour.
Jusqu'ici, nous avons vu l'utilisation de guix time-machine
exclusivement en
combinaison avec la commande guix shell
. Bien que ce soit probablement une
association des plus courantes, la commande guix time-machine
peut être
également utilisée avec les autres commandes de Guix.
Pensez-vous à d'autres cas d'utilisation possibles ?
Utilisation plus avancée
Pour la suite de cette session, nous allons rester dans l'optique de
l'utilisation de guix time-machine
en couple avec guix shell
. Nous avons vu
la mise en pratique de guix time-machine
sous la forme suivante.
guix time-machine --no-channel-files \ --commit=ee92b0fb7dfd8b55ea63254a59a1605fb870a44c -- \ shell --container gcc-toolchain mumps bash coreutils -- bash
L'option --commit
dit à la commande d'utiliser le canal officiel de Guix avec
le commit en paramètre, ee92b0fb7dfd8b55ea63254a59a1605fb870a44c
dans ce cas
précis. Puis, l'option --no-channel-files
dit à Guix de ne pas charger le
fichier de canaux du système ou celui du profil utilisateur courant. En somme,
nous considérons uniquement le canal officiel de Guix.
Cependant, il se peut qu'on ait envie d'utiliser, en plus du canal officiel, un
autre canal fournissant d'autres paquets logiciels. Par exemple, dans la section
Comment obtenir les informations sur mon installation Guix actuelle ?, nous avons vu une sortie de la commande guix describe
montrant l'utilisation de plusieurs canaux.
Pokolenie 1 22. máj 2024 02:30:17 (súčasné) guix-hpc dd9eadb zdroj repozitára: https://gitlab.inria.fr/guix-hpc/guix-hpc.git vetva: master úprava: dd9eadb6bd5b73912812594251cb7135327f84c0 guix-science-nonfree 417f86b zdroj repozitára: https://github.com/guix-science/guix-science-nonfree.git vetva: master úprava: 417f86b4819bb45df671c3276216e57d2a427156 guix-past 921f845 zdroj repozitára: https://gitlab.inria.fr/guix-hpc/guix-past vetva: master úprava: 921f845dc0dec9f052dcda479a15e787f9fd5b0a guix-science f85279b zdroj repozitára: https://github.com/guix-science/guix-science.git vetva: master úprava: f85279b8aeac3cc3e6e2aec866841c722c5663fe guix 413ef75 zdroj repozitára: https://git.savannah.gnu.org/git/guix.git vetva: master úprava: 413ef75f89ac337f7ac3331a862c7c8cdc88aa64
Comment faire pour dire à guix time-machine
d'utiliser plusieurs canaux ?
Au lieu d'utiliser l'option --commit
de guix time-machine
, nous pouvons lui
passer la liste et les spécifications (numéros de commits, …) de canaux dans
un fichier en langage Scheme en utilisant l'option --channels
ou -C
. Voici
donc à quoi ressemble un tel fichier décrivant la liste des canaux ci-dessus.
(list (channel (name 'guix-hpc) (url "https://gitlab.inria.fr/guix-hpc/guix-hpc.git") (branch "master") (commit "dd9eadb6bd5b73912812594251cb7135327f84c0")) (channel (name 'guix-science-nonfree) (url "https://github.com/guix-science/guix-science-nonfree.git") (branch "master") (commit "417f86b4819bb45df671c3276216e57d2a427156")) (channel (name 'guix-past) (url "https://gitlab.inria.fr/guix-hpc/guix-past") (branch "master") (commit "921f845dc0dec9f052dcda479a15e787f9fd5b0a") (introduction (make-channel-introduction "0c119db2ea86a389769f4d2b9c6f5c41c027e336" (openpgp-fingerprint "3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5")))) (channel (name 'guix-science) (url "https://github.com/guix-science/guix-science.git") (branch "master") (commit "f85279b8aeac3cc3e6e2aec866841c722c5663fe")) (channel (name 'guix) (url "https://git.savannah.gnu.org/git/guix.git") (branch "master") (commit "413ef75f89ac337f7ac3331a862c7c8cdc88aa64") (introduction (make-channel-introduction "9edb3f66fd807b096b48283debdcddccfea34bad" (openpgp-fingerprint "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA")))))
Pas de panique ! Nous n'aurons pas à écrire ce fichier à la main à partir de
zéro. Afin de produire ce fichier pour notre génération de Guix actuelle, nous
pouvons utiliser la commande guix describe
avec son option -f
ainsi.
guix describe -f channels
La ligne de commande ci-dessus produira automatiquemet la sortie de guix
describe
dans le format Scheme. Nous pouvons simplement rediriger cette sortie
dans un fichier Scheme, puis l'utiliser avec guix time-machine
comme suit.
guix describe -f channels > channels.scm guix time-machine --channels=channels.scm -- shell --container hello -- hello
Petit extra
Nous retrouvons une situation similaire dans le cadre de l'utilisation de la
commande guix shell
. Lorsque de la création d'environnements simples tels que
guix shell --container gcc-toolchain mumps bash coreutils -- bash
il est relativement facile de retenir et de retrouver notre ligne de commande
guix shell
. Cependant, nous pouvons être amenés à créer des envionnements
plus complexes comme, par exemple,
guix shell --pure --with-input=pastix-5=pastix-5-mkl \ --with-input=mumps-scotch-openmpi=mumps-mkl-scotch-openmpi \ --with-input=openblas=mkl --with-input=slurm=slurm@19 \ --with-git-url=gcvb=$HOME/src/gcvb \ --with-commit=gcvb=40d88ba241db4c71ac3e1fe8024fba4d906f45b1 \ --preserve=^SLURM bash coreutils inetutils findutils grep sed \ bc openssh python python-psutil gcvb slurm@19 openmpi scab
Sans entrer dans les détails, il est clair que nous pourrions mieux nous en
sortir si nous pouvions transformer cette ligne de commande en un fichier Scheme
comme dans le cas de l'utilisation de plusieurs canaux avec la commande guix
time-machine
. Eh bien, c'est possible ! Il suffit de rajouter à la commande
ci-dessus l'option --export-manifest
pour obtenir la sortie suivante.
(define transform1 (options->transformation '((with-input . "pastix-5=pastix-5-mkl") (with-input . "mumps-scotch-openmpi=mumps-mkl-scotch-openmpi ") (with-input . "openblas=mkl") (with-input . "slurm=slurm@19") (with-git-url . "gcvb=/home/marek/src/gcvb") (with-commit . "gcvb=40d88ba241db4c71ac3e1fe8024fba4d906f45b1")))) (packages->manifest (list (transform1 (specification->package "scab")) (transform1 (specification->package "gcvb")) (transform1 (specification->package "openmpi")) (transform1 (specification->package "slurm@19")) (transform1 (specification->package "gcvb")) (transform1 (specification->package "python-psutil")) (transform1 (specification->package "python")) (transform1 (specification->package "openssh")) (transform1 (specification->package "bc")) (transform1 (specification->package "sed")) (transform1 (specification->package "grep")) (transform1 (specification->package "findutils")) (transform1 (specification->package "inetutils")) (transform1 (specification->package "coreutils")) (transform1 (specification->package "bash"))))
La sortie que nous pouvons rédiriger dans un fichier Scheme appelé manifest,
puis le réutiliser avec la commande guix shell
et son option --manifest
ou
-m
comme suit.
guix shell ... --export-manifest > manifest.scm guix shell --pure --preserve=^SLURM --manifest=manifest.scm -- ...
Essayons donc d'en faire autant dans le cadre de notre Mise en situation.
guix shell --container gcc-toolchain mumps bash coreutils \
--export-manifest > manifest.scm
guix shell --container --manifest=manifest.scm -- bash
Vers un environnement logiciel reproductible
En résumé, pour assurer la reproductibilité de notre environnement logiciel géré avec Guix, nous avons besoin de deux ingrédients :
- descriptif du contenu de notre environnement – ligne de commande
guix shell
ou le fichier manifest (voir Petit extra), - descriptif de la génération de Guix utilisée pour le créer – le commit du
canal oficiel de Guix ou une liste des canaux et de leurs commits dans un
fichier Scheme (voir Comment faire pour dire à
guix time-machine
d'utiliser plusieurs canaux ?)
En pratique, dans un projet sous contrôle de version (hébergé dans un dépôt
git), nous pouvons garder deux fichiers supplémentaire, un fichier
channels.scm
et un fichier manifest.scm
.
Voyons ça en pratique !
Démonstrations
Observez les dépôts git Vers une étude expérimentale reproductible (A) et OptiTrust (B).
Le dépôt A contient une présentation rédigée en Org mode et le dépôt B un
logiciel complexe de compilation. Dans les deux dépôts, il y a un dossier
.guix
qui contient, entre autres, un fichier channels.scm
et un fichier
manifest.scm
.