Journal Étendre ou modifier sa logithèque Nix avec les overlays

Posté par (page perso) . Licence CC by-sa.
Tags :
15
10
nov.
2019

Sommaire

Le gestionnaire de paquets Nix est hautement personnalisable. Pour cela, il reprend le principe de la composition de fonctions : un paquet est en fait une fonction qui indique comment ajouter ou modifier un logiciel à partir d'un environnement logiciel d'entrée.

Ainsi, la logithèque Nix n'est qu'un ensemble de paquets qui peuvent être appliqués pour construire l'environnement logiciel final. Les overlays permettent de modifier les paquets de cet ensemble ou d'en ajouter de nouveaux.

vidéo youtube - vidéo peertube

Principe des overlays Nix

Pour ajouter un paquet personnel ou pour modifier un paquet déjà existant, Nix permet d'ajouter des overlays. Concrètement, il s'agit de fichiers Nix que l'on place dans le dossier ~/.config/nixpkgs/overlays/. Ces overlays sont alors appliqués automatiquement sur la logithèque.

Par exemple, si on ajoute le fichier ~/.config/nixpkgs/overlays/monOverlay1.nix suivant, on modifie le paquet boost de la logithèque et on y ajoute un paquet monAppli :

self: super: {

  boost = super.boost.override {
    python = self.python3;
  };

  monAppli = super.callPackage ./pkgs/monAppli.nix {};

}

Dans cet overlay, self et super sont les paramètres de la fonction à appliquer sur la logithèque d'entrée; super est la version initiale de la logithèque et self la version modifiée.

Ces modifications seront alors automatiquement appliquées, par exemple si on installe un de ces paquets ou si on lance un nix-shell qui les utilisent.

Les overlays sont détaillés dans le manuel de nixpkgs et dans le wiki nixos.

Exemple avec GNU Nano

Prenons le paquet GNU Nano et modifions-le grâce aux overlays Nix.

Le paquet de base

Ici, le paquet de base de GNU nano est la version 4.4 compilée avec les options --disable-libmagic et --enable-utf8.

$ nano --version
 GNU nano, version 4.4
 (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
 (C) 2014-2019 les contributeurs de nano
 Adr. él. : nano@nano-editor.org  Site : http://nano-editor.org/
 Compilé avec les options : --disable-libmagic --enable-utf8

Paramétrer le paquet de base

Les paquets Nix peuvent avoir des paramètres. Par exemple, le paquet nano de base contient le paramètre enableNls ? true, qui permet de régler l'option de compilation nls et est activée par défaut. Si on veut créer un paquet nano-no-nls qui reprend ce paquet mais en désactivant l'option nls, on peut ajouter le fichier ~/.config/nixpkgs/overlays/nano-no-nls.nix suivant :

self: super: {

  nano-no-nls = super.nano.override {
    enableNls = false;
  };

}

On peut alors installer notre nouveau paquet nano-no-nls (qui sera compilé automatiquement) et vérifier que nano est désormais notre version personnalisée :

$ nix-env -iA nixos.nano-no-nls
installing 'nano-4.4'
these derivations will be built:
  /nix/store/6pg25sqj2vv2jq8dn00ajbc9xx2s96r3-nano-4.4.drv
...

$ nano --version
 GNU nano, version 4.4
 (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
 (C) 2014-2019 the contributors to nano
 Email: nano@nano-editor.org    Web: https://nano-editor.org/
 Compiled options: --disable-libmagic --disable-nls --enable-utf8

Redéfinir le paquet de base

Nix permet de modifier les paquets encore plus profondément. Par exemple, on peut modifier le paquet existant nano de façon à utiliser la version 4.5 du code source de nano :

self: super: {

  nano = super.nano.overrideAttrs (oldAttrs: rec {
    pname = oldAttrs.pname;
    version = "4.5";
    src = super.fetchurl {
      url = "mirror://gnu/nano/${pname}-${version}.tar.xz";
      sha256 = "0czmz1yq8s5qcxcmfjdxzg9nkhbmlc9q1nz04jvf57fdbs7w7mfy";
    };
  });

}

Cet overlays reprend certains attributs du paquet initial (pname) et en modifie certains autres (version, src).

Si on installe le paquet nano, l'overlay est appliqué et on se retrouve bien avec la version 4.5 :

$ nix-env -iA nixos.nano
replacing old 'nano-4.4'
installing 'nano-4.5'
these derivations will be built:
  /nix/store/cg60jqfw8fk4fkkamvjrhhkkas79z0w2-nano-4.5.drv
these paths will be fetched (1.42 MiB download, 1.42 MiB unpacked):
  /nix/store/pbs1pf1vsk4zx6zis9a352j9lz88jrx2-nano-4.5.tar.xz
...

$ nano --version
 GNU nano, version 4.5
 (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
 (C) 2014-2019 les contributeurs de nano
 Adr. él. : nano@nano-editor.org  Site : http://nano-editor.org/
 Compilé avec les options : --disable-libmagic --enable-utf8

Mise en cache des paquets recompilés, avec cachix

Les overlays sont compatibles avec cachix, le service cloud de cache binaire. Par exemple, si on veut mettre en cache notre paquet nano 4.5 dans le dépôt de cache nokomprendo, on utilise la commande habituelle cachix push :

$ find /nix/store -maxdepth 1 -name "*nano-4.5*" -exec cachix push nokomprendo {} \;
pushing /nix/store/23wg5gf404zmnn8fixrg8rm38f06hqny-ncurses-6.1-20190112
pushing /nix/store/pnd2kl27sag76h23wa5kl95a76n3k9i3-glibc-2.27
pushing /nix/store/qq8nfcxvak3iic0dvw1dfk3jnr9acv4m-nano-4.5
...

Pour tester notre cache, on peut annuler l'installation de nano-4.5 et nettoyer les fichiers correspondants dans le /nix/store :

$ nix-env --rollback 
switching from generation 32 to 31

$ nix-env --delete-generations 32
removing generation 32

$ find /nix/store/ -maxdepth 1 -name "*nano-4.5*" -exec nix-store --delete {} \+
finding garbage collector roots...
deleting '/nix/store/cg60jqfw8fk4fkkamvjrhhkkas79z0w2-nano-4.5.drv'
deleting '/nix/store/9csadwrlh6yvxl55143y55i8jx893k09-nano-4.5.tar.xz.drv'
deleting '/nix/store/jg6kivw3b0c2dak03ylvsn72jnd38774-nano-4.5-info'
deleting '/nix/store/pbs1pf1vsk4zx6zis9a352j9lz88jrx2-nano-4.5.tar.xz'
deleting '/nix/store/s9y641283gbkv1wpsnl5yr4b8vqsja0r-user-environment'
deleting '/nix/store/yjh8mcpxbyq8qbb6ndw6jizd3knfsclg-user-environment.drv'
deleting '/nix/store/y0856674ymjdzp277scsvg3qa084381i-env-manifest.nix'
deleting '/nix/store/qq8nfcxvak3iic0dvw1dfk3jnr9acv4m-nano-4.5'
deleting '/nix/store/trash'
deleting unused links...
note: currently hard linking saves -0.00 MiB
8 store paths deleted, 3.68 MiB freed

Désormais, si on active le cache et qu'on lance l'installation de notre paquet nano-4.5, Nix ne recompile pas le paquet mais télécharge directement le binaire depuis le cache :

$ cachix use nokomprendo
Configured https://nokomprendo.cachix.org binary cache in /home/nokomprendo/.config/nix/nix.conf

$ nix-env -iA nixos.nano
installing 'nano-4.5'
these paths will be fetched (0.51 MiB download, 2.19 MiB unpacked):
  /nix/store/jg6kivw3b0c2dak03ylvsn72jnd38774-nano-4.5-info
  /nix/store/qq8nfcxvak3iic0dvw1dfk3jnr9acv4m-nano-4.5
copying path '/nix/store/jg6kivw3b0c2dak03ylvsn72jnd38774-nano-4.5-info' from 'https://nokomprendo.cachix.org'...
copying path '/nix/store/qq8nfcxvak3iic0dvw1dfk3jnr9acv4m-nano-4.5' from 'https://nokomprendo.cachix.org'...
building '/nix/store/yjh8mcpxbyq8qbb6ndw6jizd3knfsclg-user-environment.drv'...
created 1185 symlinks in user environment

$ nano --version
 GNU nano, version 4.5
 (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
 (C) 2014-2019 les contributeurs de nano
 Adr. él. : nano@nano-editor.org  Site : http://nano-editor.org/
 Compilé avec les options : --disable-libmagic --enable-utf8

Conclusion

Avec les overlays, Nix permet de modifier très facilement la logithèque (ajouter des nouveaux paquets, modifier les paquets existants…). Pour cela, il suffit d'ajouter nos fichiers d'overlays dans le dossier ~/.config/nixpkgs/overlays/ et les modifications correspondantes seront automatiquement appliquées. Les overlays s'intègrent complétement à l'écosystème Nix; on peut notamment mettre en cache les binaires générés et les réutiliser sur une autre machine sans avoir à les recompiler.

  • # Bon mode de deployment

    Posté par (page perso) . Évalué à 5 (+3/-0).

    Merci pour le journal.

    Pour la petite note:

    Nous utilisons Nix + overlays comme medium pour déployer toute la stack logiciel de la boite où je travaille.

    • Une version de nixpkgs taggué nous fournit tous l'environnement existant.
    • Nos softs sont ajoutés comme un seul overlay par dessus.

    • C'est suffisament puissant et stable pour deployer une stack d'une centaine de logiciels sur environs 200 machines en production et de manière synchrone.

    • [^] # Re: Bon mode de deployment

      Posté par (page perso) . Évalué à 2 (+1/-1).

      Merci pour ce retour d'expérience intéressant. Vous utilisez un système de cache, comme hydra ou cachix, pour éviter les recompilations ?

      • [^] # Re: Bon mode de deployment

        Posté par (page perso) . Évalué à 2 (+0/-0).

        Merci pour ce retour d'expérience intéressant. Vous utilisez un système de cache, comme hydra ou cachix, pour éviter les recompilations ?

        Oui, mais purement based sur du S3. Les résultats de build sont généré par Jenkins.

      • [^] # Re: Bon mode de deployment

        Posté par (page perso) . Évalué à 2 (+0/-0).

        Nous on fait pareil et c'est S3 qui fait le cache aussi.

        On a pas forcement testé cachix: toute notre infrastructure d'usine de code (gerrit, jenkins, gitlab, git-lfs) est déjà sur amazon, donc déployer un serveur de plus (configuré avec nix(os)) pour faire le cache était naturel.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.