Marek Felšöci

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 ?

Rien qu'une machine à voyger dans le temps afin de pouvoir exécuter ma ligne de commande guix shell comme si nous étions de retour au printemps 2022.

Pas de problème, Guix a ce qu'il me faut ! C'est là que les commandes guix time-machine [5] et guix describe [6] vont entrer en jeu.

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.

guix-repo.png

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.

guix-repo-timeline.png

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 :

  1. descriptif du contenu de notre environnement – ligne de commande guix shell ou le fichier manifest (voir Petit extra),
  2. 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.

Réferences

[1]
“GNU Guix software distribution and transactional package manager.” https://guix.gnu.org.
[2]
P. Amestoy, I. S. Duff, J. Koster, and J.-Y. L’Excellent, “A fully asynchronous multifrontal solver using distributed dynamic scheduling,” Siam journal on matrix analysis and applications, vol. 23, no. 1, pp. 15–41, 2001.
[3]
P. Amestoy, A. Buttari, J.-Y. L’Excellent, and T. Mary, “Performance and Scalability of the Block Low-Rank Multifrontal Factorization on Multicore Architectures,” Acm transactions on mathematical software, vol. 45, pp. 2:1–2:26, 2019.
[4]
“Invoquer guix shell (Manuel de référence de GNU Guix).” https://guix.gnu.org/sk/manual/fr/html_node/Invoquer-guix-shell.html.
[5]
“Invoquer guix time-machine (Manuel de référence de GNU Guix).” https://guix.gnu.org/en/manual/devel/fr/html_node/Invoquer-guix-time_002dmachine.html.
[6]
“Invoquer guix describe (Manuel de référence de GNU Guix).” https://guix.gnu.org/en/manual/devel/fr/html_node/Invoquer-guix-describe.html.
[7]
“Canaux (Manuel de référence de GNU Guix).” https://guix.gnu.org/sk/manual/fr/html_node/Canaux.html.
[8]
“Invoquer guix pull (Manuel de référence de GNU Guix).” https://guix.gnu.org/sk/manual/fr/html_node/Invoquer-guix-pull.html.

Last update on 27/05/2024


This site is proudly powered by Org mode for Emacs on the servers of Websupport, spol. s r. o.

Source code of the site is publicly available on GitHub.

Featured icons come from the open-source sets Chicago95 and flag-icons.

Content is available under the Creative Commons BY NC ND 4.0 International license unless otherwise stated.

Creative Commons License