URL: https://linuxfr.org/news/nix-1-7-nixpkgs-et-nixos-14-04-guix-0-6 Title: Nix 1.7, Nixpkgs, NixOS 14.04, Guix 0.6 Authors: galbolle BAud, ZeroHeure, palm123, Nÿco, claudex, Benoît Sibaud, Xavier Teyssier, patrick_g, olivierweb et sebas Date: 2014年01月09日T22:10:41+01:00 License: CC By-SA Tags: guix, nixos, nix, ubuntu, fedora et firefox Score: 55 Quelques mots d'introduction : * Nix est un système de paquets * nixpkgs la collection de paquets associée * NixOS la distribution construite avec nix et nixpkgs * Guix est un dérivé GNU de Nix ![Logo nixos](http://pix.toile-libre.org/upload/original/1398976930.png) ![Logo guix](http://pix.toile-libre.org/upload/original/1398977064.png) Nix permet d'utiliser des paquets sources, comme sous Gentoo ou Arch, mais aussi des paquets binaires plus traditionnels. Comme presque tous les systèmes de gestion de paquets, il permet la gestion des dépendances entre paquets. Ses principes de fonctionnement originaux lui permettent d'implémenter de façon sûre des fonctionnalités souvent peu stables ou absentes des autres gestionnaires de paquets, notamment : installation de paquets dans le répertoire des utilisateurs, déploiement distribué, mélanges paquets sources et binaires et mises à jour réversibles. Il s'agit de la poursuite par la communauté du travail commencé par Eelco Dolstra dans sa thèse à la Technische Universiteit de Delft. La version 14.04 de NixOS est sortie le premier mai. Cette dépêche présentera l'écosystème Nix, puis les nouveautés de nixpkgs et NixOS 14.04, de Nix 1.7 ainsi que Guix, le dérivé GNU de Nix. ---- [Le projet Nix](http://nixos.org/) [Le gestionnaire de paquets Nix](http://nixos.org/nix/) [La distribution Nixos](http://nixos.org/nixos/) [Présentation de nix/nixos au fosdem 2014](http://ftp.belnet.be/FOSDEM/2014/H1309_Van_Rijn/Saturday/NixOS_declarative_configuration_Linux_distribution.webm) [La thèse séminale d'Eelco Dolstra](http://nixos.org/~eelco/pubs/phd-thesis.pdf) [Le canal irc de nix / nixos](irc://chat.freenode.net/#nixos) [La liste de diffusion de nix / nixos](http://lists.science.uu.nl/mailman/listinfo/nix-dev) [Des webservices déclaratifs avec NixOS (présentation par Joachim Schiele, partie théorique)](http://media.ccc.de/browse/conferences/eh2014/EH2014_-_5752_-_de_-_degerloch_-_201404201445_-_deklarativ_webservices_unter_nixos_beschreiben_-_joachim_schiele.html) [Une présentation général et démonstration de NixOS (partie pratique de la présentation par J Shiele)](http://media.ccc.de/browse/conferences/eh2014/EH2014_-_5743_-_de_-_shack-seminarraum_-_201404181915_-_nixos_als_serversystem_in_der_praxis_-_joachim_schiele.html) [Distrowatch reviews: Deploying Software Sensibly with NixOS 13.10](http://distrowatch.com/weekly.php?issue=20140317#feature) ---- # Pourquoi utiliser Nix et NixOS ? Nix emprunte sa philosophie « fonctionnelle pure » aux langages de programmation comme Haskell. Cela signifie que plutôt que de modifier _en dur_ le système et ses fichiers, Nix permet de construire différentes « configurations » (un ensemble de paquets installés avec la configuration de la machine) et de basculer de l'une à l'autre. Grâce à cette spécificité, il propose son lot de fonctionnalités originales, absentes de la plupart des systèmes classiques de gestion de paquets : * possibilité d'annuler une mise à jour, de revenir à une ancienne version ; * pour procéder à une mise à jour ou une installation de paquet, on peut construire une machine virtuelle avec la nouvelle version du système, la tester, puis basculer le système si tout va bien ; * dépendances exactes ; * installation de paquets sans accès root ; * « USE FLAGS » façon Gentoo, compatibles avec des paquets binaires ; * cohabitation entre plusieurs versions du même paquet, ou de la même bibliothèque ; * builds reproductibles / purement fonctionnels. Le développement de nix et NixOS est très ouvert. Comme il sied à un projet de recherche en voie de pérennisation il passe par des [projets github](http://www.github.com/nixos) pour chacun des composants et les contributions sont bien acceptées. ### Les cousins 0install et pisi Le système _0install_ propose des fonctionnalités qui se rapprochent de celles de nix, en particulier la possibilité d'installer des paquets sans accès root. NixOS prend en charge toute la configuration du système (ou presque), tandis que 0install ne s'occupe que de paquets utilisateurs au sein d'un système hôte. Ainsi, 0install ne permet pas de rendre réversible la mise à jour des composants centraux du système, comme par exemple la libc. Il ne permet pas non plus d'intégrer l'installation et la configuration des paquets et encore moins de gérer le déploiement. De plus, 0install fonctionne en interceptant des appels système, ce qui le rend moins portable que nix. Tout comme avec 0install, nix permet de proposer des [liens d'installation en un clic](http://nixos.org/nix/manual/#sec-one-click) utilisables sans le mot de passe root. Cliquer sur un tel lien, [par exemple celui pour quantumminigolf](http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest/pkg/quantumminigolf-1.1.1-x86_64-linux-10728668.nixpkg), permet d'installer un paquet et toutes ses dépendances. Une autre distribution Linux, [Pardus] (http://www.pardus.org.tr/), une distribution turque, a utilisé à un moment un gestionnaire de paquets un peu comparable avec nix, [Pisi](http://wiki.pisilinux.org/en/index.php?title=How-To:_Package_Management). Il propose une partie des fonctionnalités de nix, mais avec une approche moins théorisée. Pisi est aujourd'hui repris dans [Pisi Linux](http://www.pisilinux.org), qui reste encore confidentiel. NixOS, Guix et Pisi Linux sont aujourd'hui les seules distributions à utiliser un système de paquet comparable à nix. # Utilisation de nix et installation sur une distribution classique ## Survie sous nix ### Les commandes de base Les commandes de base de nix, détaillées dans le [manuel](http://nixos.org/nix/manual/) sont assez semblables à celles d'autres gestionnaires de paquets: * `nix-env --install firefox` permet l'installation d'un paquet, binaire si une version binaire convenable est disponible, sinon depuis les sources. Notez l'absence de `sudo`... * `nix-channel --update` permet de mettre à jour la liste des paquets binaires disponibles ; * `nix-env -qa '*'` donne la liste de tous les paquets disponibles ; * `nix-env -e hello` permet de supprimer un paquet ; * `nix-env -u '*'` permet de mettre à jour tous les paquets. Les paquets sources sont dans un [dépôt git](https://github.com/NixOS/nixpkgs) qu'il faudra cloner et tenir à jour si l'on veut personnaliser ses paquets, comme l'arbre des ports sous freeBSD, par exemple. ### Où les choses deviennent intéressantes Nix propose aussi des opérations qui ne sont pas disponibles dans d'autres systèmes de gestion de paquets : * `nix-env --rollback`: si la dernière opération (par exemple un nix-env -u) n'a pas donné les résultats souhaités, elle permet de l'annuler ; * `nix-env --switch-generation 82` permet de revenir à une ancienne configuration du système (`nix-env --list-generations` pour obtenir la liste de ces configurations) ; * `nix-env -i juk --profile /nix/var/nix/profiles/music-lover` permet d'installer un paquet dans un _profil_, et `nix-env --switch-profile /nix/var/nix/profiles/music-lover` permet de passer d'un profil à l'autre. Cela permet de disposer de plusieurs jeux de paquets entre lesquels on peut basculer suivant les besoins ou pour contourner d'éventuelles incompatibilités (par exemple entre deux versions d'un même paquet, dont on peut avoir besoin suivant le contexte). Ça permet aussi de créer des ensembles de paquets de référence pour utilisation ultérieure. Ainsi, dans une université, on crée un environnement logiciel spécifique à un TP et on peut le donner à tous les étudiants le temps de ce TP. L'un des avantages de nix, c'est que les simples utilisatrices et utilisateurs peuvent installer des paquets. Finies les re-compilations dans les _home_ depuis les sources du paquet .deb ou .rpm parce qu'on n'a pas le droit d'écrire dans `/usr` ! Avec nix, le même paquet peut-être installé par root pour le système ou par un utilisateur ou une utilisatrice dans son home. En outre, si plusieurs personnes installent le même paquet (avec les mêmes options aux petits oignons et avec les mêmes versions des dépendances), elles partagent de façon sécurisée les binaires et autres fichiers de données du paquet. ## Installation sur une distribution classique De même, nix peut cohabiter avec un système de paquets classique pour permettre d'installer des paquets dans son home sur n'importe quelle distribution, avec le confort d'un vrai gestionnaire de paquets. Pour installer nix sur un système Linux hôte autre que NixOS, il faut récupérer un paquet «classique» pour votre distribution sur le site de nix : * [version 1.7, la dernière en date](http://hydra.nixos.org/release/nix/nix-1.7), avec les sources et des paquets binaires pour Debian, Ubuntu 10.10 à 13.10, Fedora 16 à 19, des binaires indépendants de la distribution pour Linux, FreeBSD et Darwin/MacOS X ; * [version en cours de développement](http://hydra.nixos.org/job/nix/trunk/tarball) avec le même choix de formats de paquets. Avec les paquets RPM et Debian, nix est alors installé en mode mono-utilisateur : seul root peut installer des paquets que tout le monde peut ensuite utiliser. C'est un peu dommage, car on perd une spécificité importante de nix. Il faut alors passer nix en mode multi-utilisateurs, comme indiqué [dans le manuel](http://releases.nixos.org/nix/nix-1.7/manual/#ssec-multi-user). Pour cela, il faut : - créer des utilisateurs `nixbld1, nixbld2, ...` qui pourront lancer les constructions de paquets qui seront ensuite partagés par tous ; - créer un groupe `nixbld` et y ajouter `nixbld1, nixbld2` et seulement eux ; - donner au groupe `nixbld` les droits en écriture sur `/nix/store` : ```bash chgrp nixbld /nix/store chmod 1775 /nix/store ``` - ajouter la ligne `build-users-group = nixbld` ; - lancer `nix-daemon` au démarrage de la machine ; - dans le `.profile` de chaque utilisateur ou utilisatrice de la machine, ajouter : ``` export NIX_REMOTE=daemon source /etc/profile.d/nix.sh ``` Ces solutions permettent de faire cohabiter nix avec un gestionnaire de paquets classique, à condition d'avoir un accès root pour installer nix. Dans le cas où les prosélytes de nix n'ont pas d'accès root à la machine, il leur est pour l'instant possible de l'utiliser, mais en perdant le bénéfice des paquets binaires. Il faut suivre une [procédure décrite sur le wiki de nix](https://nixos.org/wiki/How_to_install_nix_in_home_%28on_another_distribution%29). En effet, les paquets binaires de nix sont identifiés par un hash de leur contenu et de leurs dépendances ; ce hash tient donc notamment compte du préfixe du _store_ nix, c'est-à-dire l'endroit où sont réellement stockés les fichiers de chaque paquet (cf. infra). Les hashs des paquets (et de leur dépendances) vont donc différer entre la version standard (où le store est dans `/nix/store`) et une installation complètement dans `/home/camille`, où le store sera dans `/home/camille/nix/store`. Il arrive aussi que ces chemins se retrouvent codés en dur entre un paquet et ses dépendances. Il faut alors réécrire ces chemins à l'intérieur des binaires, ce qui n'est pour l'instant pas fait. Néanmoins, le projet Nix travaille [dans nix](https://github.com/NixOS/nix/issues/16) et [dans nixpkgs](https://github.com/NixOS/nixpkgs/issues/1605) pour permettre de générer des paquets binaires portables vers les installations où le _store_ est situé dans un endroit non standard, par exemple dans un répertoire home. Une fois ce projet abouti, il sera possible d'utiliser nix pour remplacer chacun des systèmes de paquets _ad hoc_ fonctionnant utilisateur par utilisateur, qu'il s'agissent d'extensions firefox, emacs, ou eclipse, ou encore de bibliothèques Python (pip), Ruby (gems), Java (maven), OCaml (opam) ou Haskell (cabal). Le troll en moi dirait que chacun de ces systèmes _ad hoc_ reproduit une version subtilement (ou pas) bugguée de nix, et que ces implémentations subtilement divergentes représentent une énorme quantité d'efforts vains (sans compter [le temps](http://3ofcoins.net/tag/dependency-hell/) [perdu](http://carlo-hamalainen.net/blog/2014/3/3/cabal-hell-workaround) [dans](http://en.wikipedia.org/wiki/JAR_hell#JAR_hell) [les bugs](http://cupofjava.de/blog/2013/02/01/fight-dependency-hell-in-maven/) [et défauts de conception de ces outils](http://engineering.prezi.com/blog/2013/04/19/snakebasket/)). ## Contenu de nixpkgs __nixpkgs__ est la collection officielle de paquets (ou « dérivations ») pour nix et donc aussi pour NixOS. Elle contient tout type d'application, dont un bureau KDE complet. En revanche, Gnome3 n'était pas disponible jusqu'à la dernière version (14.04) : décrire la construction de cet environnement de bureau sous forme de dérivation nix, c'est-à-dire en donnant explicitement toutes les dépendances de construction s'était avéré trop complexe par rapport aux forces disponibles. Le choix de paquets est plus restreint que dans d'autres distributions plus populaires et l'on se retrouve rapidement à franchir la frontière entre utilisation passive et création ou amélioration de paquets. La version 14.04 de nixpkgs contient 4314 dérivations, qui correspondent (autant qu'il est possible pour la communauté) à une version récente et peu patchée des logiciels. On est donc plus dans la démarche d'Arch que dans celle de Debian. L'un des traits notable de la communauté nix, c'est son goût pour le langage Haskell ; dans ce domaine, c'est certainement l'une des collections de paquets les plus à jour qui soient. Chaque paquet est défini par une dérivation, c'est-à-dire une description de la façon de le construire à partir de ses dépendances. Chacune des dépendances peut être soit un autre paquet, soit une valeur (entier, booléen, chaîne de caractère...), ce qui permet de rendre les dérivations personnalisables, à la manière des `use_flags` de Gentoo. Pour ce faire, on va dans le fichier `~/.nixpkgs/config.nix` et on peut y changer une variable comme `config.pulseaudio` pour désactiver `pulseaudio` et sa prise en charge dans toutes les applications (par défaut, nix construit des paquets qui utilisent pulseaudio). Le fichier `~/.nixpkgs/config.nix` permet également via `packageOverrides` d'ajouter ses propres paquets à ceux de `nixpkgs`, voire de les substituer à ceux fournis par `nixpkgs`. # Fonctionnement de nix ## Le store, l'environnement En utilisant nix, on se rend compte que si la première installation d'un paquet est une opération non-triviale (elle implique le téléchargement et la compilation éventuelle), en revanche, le passage d'un profil à un autre ou l'installation d'un paquet déjà installé dans un second profil est immédiate. C'est que `nix` stocke le contenu des paquets dans un endroit commun, quels que soient le ou les profils dans lesquels ce paquet est considéré comme installé. Cet endroit est le _store_, situé (sauf installations bidouillées jusqu'au trognon) dans `/nix/store`. Un `which firefox` sur un système où firefox est un paquet nix nous permet de constater que le cœur de nix est un empilement de liens symboliques: ![Les couches de liens symboliques de nix](http://nixos.org/nix/manual/figures/user-environments.png) Ainsi, l'exécutable firefox est stocké dans un sous-répertoire de `/nix/store` différent pour chaque version présente sur le système ; s'il fait référence à une bibliothèque ou à un autre exécutable, celle-ci sera elle aussi dans son répertoire propre ; une mise à jour ne viendra donc pas modifier la version de la dépendance à laquelle firefox fait référence. Pour chaque paquet, le hash qui sert d'identifiant au répertoire contenant les données du paquet est un hash non seulement des sources du paquet, mais aussi de ses dépendances. Ceci garantit que deux exécutables de paquets ayant le même hash auront exactement le même comportement. On peut ainsi sans risque partager des paquets binaires en présence de « personnalisation » à la Gentoo. Lors d'une mise à jour, un nouveau répertoire est créé pour chaque paquet, avec une nouvelle version du paquet. Ensuite, un nouveau profil est créé, avec des liens pointant à l'intérieur de chacun des paquets du profil. Enfin, le profil personnel (`~/.nix-profile`) est mis à jour. Ainsi, plusieurs utilisateurs et utilisatrices peuvent partager des versions présentes dans différents sous-répertoires du store (`/nix/store`) et ne pas avoir à les recompiler de leur côté, sans qu'aucun n'ait d'accès root. Les mises à jour se font alors séparément, sauf pour les paquets système. Ainsi, les collègues qui passent à firefox 29 ne cassent pas le firefox 28 des autres. ## Anatomie d'une dérivation nix Pour construire un paquet, on part de ses dépendances et d'une **dérivation** qui indique comment assembler ces dépendances. Pour les logiciels les plus courants, pour l'installation desquels la séquence `./configure; make; make install` suffit, les dérivations sont très faciles à écrire. Ainsi pour emboss, un logiciel de biologie moléculaire, on utilise le fichier suivant: ``` {stdenv, fetchurl, readline, perl, libX11, libpng, libXt, zlib}: ``` - une première ligne pour spécifier les dépendances. La dérivation étant une fonction, les dépendances sont ses arguments. S'il y avait des « use_flags », ils seraient aussi spécifiés comme arguments de la dérivation (ce n'est pas le cas ici). Dans la suite (le corps de la fonction), chacun des arguments -- par exemple `zlib` -- désignera le chemin vers le paquet correspondant dans le store -- par exemple `/nix/store/12345...zlib-1.2.3`. ``` stdenv.mkDerivation { ``` - Un appel à la fonction standard `mkDerivation`, qui construit une dérivation à partir d'informations de base qui vont suivre. On remarque que cette fonction est définie dans `stdenv`, une des dépendances de la dérivation. ``` name = "emboss-6.0.1"; src = fetchurl { url = ftp://emboss.open-bio.org/pub/EMBOSS/EMBOSS-6.0.1.tar.gz; sha256 = "0g939k9wmpvmy55hqmbbzj6kj6agg4izymv492zqiawxm812jd9y"; }; ``` - L'argument de `mkDerivation` est une structure, avec des champs comme le nom du paquet construit par la dérivation, ou la localisation de sa source. La source est obtenue par un appel à la fonction `fetchurl`, elle aussi donnée dans les dépendances. ``` buildInputs = [readline perl libpng libX11 libXt zlib]; ``` - `buildInputs` indique lesquelles des dépendances sont mises dans l'environnement du constructeur (_builder_). Ici, les exécutables `readline` et `perl` seront placés dans son `PATH`, tandis que les chemins des en-têtes et fichiers objets des bibliothèques comme `libpng` seront dans les variables d'environnement du compilateur et de l'éditeur de liens. ``` meta = { description = "EMBOSS is 'The European Molecular Biology Open Software Suite'"; longDescription = ''EMBOSS is a free Open Source software analysis package specially developed for the needs of the molecular biology (e.g. EMBnet) user community, including libraries. The software automatically copes with data in a variety of formats and even allows transparent retrieval of sequence data from the web.''; license = "GPL2"; homepage = http://emboss.sourceforge.net/; }; } ``` - Finalement, on indique les méta-données de la dérivation ; c'est tout. Pour des paquets moins standards, on peut aussi changer une des étapes de construction, appliquer des patches ou autres, mais nous n'aborderons pas ces points ici, ils suivent la même logique. Cette dérivation est une fonction, pour pouvoir l'utiliser il faut lui passer ses arguments. C'est ce qui est fait dans le fichier `pkgs/toplevel/all-packages.nix`, où on trouvera les lignes : ``` emboss = callPackage ../applications/science/biology/emboss { }; ``` On appelle la fonction définie par la dérivation pour `emboss`. La fonction `callPackage` passe par défaut à la dérivation les variables locales dont le nom correspond à ceux de ses arguments, donc la valeur de `stdenv`, `perl`, `libpng` etc. On aurait aussi pu écrire l'importation du fichier et l'appel explicitement : ``` emboss = (import ../applications/science/biology/emboss) { stdenv = stdenv, perl = perl, ...}; ``` ### Dérivations engendrées automatiquement De nombreux langages de programmation proposent leur propre gestionnaire de paquets. Sur un système classique, cela permet de contourner l'impossibilité d'installer des paquets sans accès root, ainsi que de permettre de faire cohabiter des paquets « système » stables, et des versions de développement récentes. On a ainsi `pip` pour Python, `npm` pour Node.js, `gems` pour Ruby ou encore `cabal` pour Haskell. Sous un système nix, ces fonctionnalités ne sont pas nécessaires et ces systèmes sont donc redondants. Cependant, chacun des paquets qui y sont définis contiennent des informations de dépendances. Nix dispose d'outils pour les récupérer et définir automatiquement des dérivations ; on a ainsi `cabal2nix` pour Haskell ou `npm2nix` pour Node. ## Développement sous nix Nix et NixOS sont particulièrement adaptés pour les développeurs et développeuses dont les besoins en termes de configuration logicielle peuvent varier en fonction des projets, voire au sein de chacun d'entre eux. Il est possible sous nix de développer chaque projet dans son propre environnement logiciel, sans interférences et sans recourir à des machines virtuelles. ### La petite histoire de rsCoinCoin Supposons par exemple que nous décidions de lancer le projet `rsCoinCoin` de développement d'un client pour la tribune d'un site de nouvelles francophone sur l'actualité de Linux et des logiciels libres. Nous allons développer ce projet en `Rust`, un langage moderne et ~~pas fini~~ en évolution continue. On commence benoîtement par installer le compilateur Rust : ```bash jacques$ nix-env -i rust jacques$ rustc --version rustc 0.9 host: i686-unknown-linux-gnu ``` Voilà, le compilateur Rust est installé. Nous avons fait l'installation dans notre _profil_ ; les autres utilisateurs et utilisatrices de la machine n'y voient que du feu. ```bash jacques$ su denis denis$ rustc --version The program ‘rustc’ is currently not installed. You can install it by typing: nix-env -i rust ``` ## Utilisation de nix pour gérer des « profils de développement » Ainsi donc, si parmi les utilisateurs de ce système NixOS, il y a une développeuse du compilateur Rust, Suzanne, qui utilise une version plus récente du langage, elle aura dans son profil une autre version de Rust : ```bash suzanne$ rustc --version rustc 0.10 host: i686-unknown-linux-gnu ``` Cette situation est parfaitement normale sous nix, les paquets des deux personnes sont des paquets systèmes parfaitement normaux et il n'y a pas besoin de prévoir spécifiquement paquet par paquet que plusieurs versions puissent cohabiter. ### Création d'un nouveau profil Il est même possible de se créer plusieurs profils et de basculer de l'un à l'autre. Ainsi, lorsque notre développeuse veut repasser en Rust 0.9 pour participer au développement de rsCoinCoin, elle se crée un « profil » `rust09` vers lequel elle basculera son shell pour développer rsCoinCoin. ``` bash suzanne$ ls -ld ~/.nix-profile lrwxrwxrwx 1 suzanne suzanne 46 22 avril 16:44 /home/suzanne/.nix-profile -> /nix/var/nix/profiles/per-user/suzanne/default suzanne$ export my_profiles_dir=/nix/var/nix/profiles/per-user/suzanne suzanne$ nix-env -u rust-0.9 --always -p $my_profiles_dir/rust09 --from-profile $my_profiles_dir/default ``` On a bien rust 0.9 dans ce profil : ```bash suzanne$ nix-env --switch-profile $my_profiles_dir/rust09 suzanne$ ls -ld ~/.nix-profile lrwxrwxrwx 1 suzanne suzanne 46 22 avril 16:44 /home/suzanne/.nix-profile -> /nix/var/nix/profiles/per-user/suzanne/rust09 suzanne$ rustc --version rustc 0.9 host: i686-unknown-linux-gnu ``` En revanche, dans le profil par défaut, on a toujours le 0.10 : ```bash suzanne$ nix-env --switch-profile $my_profiles_dir/default suzanne$ ls -ld ~/.nix-profile lrwxrwxrwx 1 suzanne suzanne 46 22 avril 16:44 /home/suzanne/.nix-profile -> /nix/var/nix/profiles/per-user/suzanne/default suzanne$ rustc --version rustc 0.10 host: i686-unknown-linux-gnu ``` Notons que comme Jacques et le profil `rust09` de Suzanne utilisent la même version de `rustc`, l'exécutable n'est installé qu'une fois sur le système. ### `nix-shell` et le fichier `rsCoinCoin/shell.nix` Nous pouvons aller plus loin, et lier le changement d'environnement avec le projet. Pour cela, nous allons décrire l'environnement de construction et d'utilisation de rsCoinCoin avec un fichier `shell.nix` du même goût que le `default.nix` que nous avons vu plus haut pour `emboss`. Ce fichier nous permet de communiquer au reste du monde, développeuses et utilisateurs comment déployer rsCoinCoin. Il nous permet aussi de passer nous-même dans cet environnement de développement de `rsCoinCoin` avec un sous-shell. Comme nous nous apprêtons à écrire une dérivation qui va rester autonome vis-à-vis du reste de nixpkgs (pour l'instant), elle va prendre une forme un peu différente, avec une importation explicite des dépendances depuis nixpkgs : ```haskell let nixpkgs = (import {}) inherit (nixpkgs) rust stdenv gtk; #... autres dépendances in stdenv.mkDerivation (self: { name = "rsCoinCoin"; # etc, cf ci dessus }) ``` On n'a plus ici une fonction, mais directement la définition d'une valeur-dérivation. À partir de celle-ci on a un environnement, et la commande `nix-shell` nous permet de lancer un shell dans cet environnement. On peut ainsi utiliser une version différente des bibliothèques pour différents projets sans conflits, et encore une version différente en tant qu'utilisateur final pour construire nos paquets quotidiens. # NixOS et ses particularités techniques ## Présentation générale de NixOS Autour du gestionnaire de paquets nix, il existe une distribution GNU/Linux: __NixOS__. Utiliser NixOS permet de profiter des avantages de nix et de son approche _purement fonctionnelle_ dans tous les aspects de la configuration du système. Pour le reste, y a-t-il réellement encore une différence entre distributions ? ## Utilisation de `nixos-rebuild` pour les mises à jour ## `nixos-rebuild` La mise à jour du système se fait par la commande `nixos-rebuild`, qui comme son nom l'indique permet de reconstruire le système avec de nouveaux paquets système ou une nouvelle configuration système. Elle assure le même rôle que `nix-env`, mais elle prend en charge la configuration d'un système complet, plutôt que simplement celle d'une collection de logiciels. Intéressons-nous d'abord au cas d'une mise à jour des paquets du système, sans changement de la configuration locale. On commence par mettre à jour le canal des paquets : ``` bash $ sudo nix-channel --update ``` soit l'équivalent de : ```bash $ sudo apt update ``` ### L'opération switch (et rollback) Une fois les définitions de paquets mises à jour, on peut construire le nouveau système et y basculer : ```bash $ sudo nixos-rebuild switch ``` ce qui correspond (superficiellement) à : ```bash $ sudo apt upgrade ``` La différence avec un système classique, c'est qu'une telle mise à jour est réversible. _Catastrophe ! La mise à jour a tout cassé, la police du terminal est passée en Comic Sans._ Que faire ? Un simple ```bash $ sudo nixos-rebuild switch --rollback ``` nous ramène à la version précédente. _Diantre ! La mise à jour a tout cassé, le système ne démarre plus._ Pas de panique, la version précédente du système est accessible depuis le menu grub (la capture d'écran est _un peu_ datée, un nixos récent utiliserait grub2) : ![menu grub avec la version précédente accessible](http://nixos.org/nixos/screenshots/nixos-grub.png) ### L'opération build-vm Pour éviter les déconvenues du paragraphe précédent, nixos propose une opération `nixos-rebuild build-vm` qui crée une machine virtuelle correspondant à la nouvelle configuration. On peut ainsi en tester le fonctionnement par : ``` bash $ nixos-rebuild build-vm $ ./result/bin/run-*-vm ``` On pourra ensuite basculer le système hôte vers cette configuration si elle donne satisfaction. ### Profils système De même que les profils utilisateurs, on peut utiliser ``` bash $ nixos-rebuild build -p autreProfil ``` pour créer un nouveau profil système. Celui-ci apparaîtra dans le menu grub, mais ne modifiera pas le système par défaut. ## Le fichier /etc/nixos/configuration.nix L'idée centrale de `nix`, c'est que la composition et le fonctionnement de chaque composant du système ne dépend que des entrées de la dérivation correspondante. Comme nous venons de le voir, la commande `nixos-rebuild` prend en entrée une description du système que l'on souhaite obtenir, et le met en place (sur la machine ou dans une machine virtuelle). Le fichier `/etc/nixos/configuration.nix` permet de donner cette description complète du fonctionnement du système : chaque service qui peut tourner sur un système NixOS a une section dans ce fichier qui définit sa configuration. La commande `nixos-rebuild` aura pour effet de mettre en place les changements de configuration. Il est bien sûr possible d'utiliser `import` pour découper ce fichier, mais nixos n'impose pas de découpage, ce qui permet de grouper des outils liés. Voici par exemple la section consacrée à l'internationalisation : ```haskell i18n = { consoleFont = "lat9w-16"; consoleKeyMap = "fr"; defaultLocale = "fr_FR.UTF-8"; }; ``` ou celle pour SLiM, un utilitaire de login graphique : ```haskell services.xserver.displayManager.slim.enable = true; services.xserver.displayManager.slim.defaultUser = "dominique"; services.xserver.displayManager.slim.autoLogin = true; ``` Avec ce système, il n'est théoriquement pas nécessaire d'apprendre d'autres langages de configuration que `nix`, qui a de plus l'avantage d'être Turing-puissant. Évidemment ce confort a des limites, avec des variables du type « `machin.extraConfig` : chaîne à ajouter à la fin du fichier `/etc/machin.conf` » et la nécessité d'écrire une couche de transformation entre le langage `nix` et le fichier de configuration. Ce système permet aussi d'intégrer la configuration du système et la définition des paquets à installer. Ainsi, la ligne suivante dans configuration.nix : ```haskell fileSystems.myWindowsDisk.fsType = ntfs; ``` indique que `myWindowsDisk` doit être monté en NTFS, mais elle provoquera aussi l'installation du paquet `ntfs3G` de manipulation de systèmes de fichiers `NTFS`. Enfin, comme tous les changements de configuration sont traités par `nix`, il est possible d'utiliser `nixos-rebuild --rollback` pour revenir sur les changements de configuration. Il est également possible d'utiliser des _profils_ pour basculer entre plusieurs configurations. On a ainsi un système de gestion de version de la configuration qui sait quelles sont les opérations à faire (démons à relancer entre autres) pour basculer pour basculer d'une configuration à une autre. L'utilisation de `systemd` s'avère indispensable pour pouvoir faire cette bascule de façon fiable. ## NixOS contre la FHS ![Une arborescence inhabituelle depuis 2007]( http://nixos.org/nixos/screenshots/nixos-terminals.png) Il existe une norme sur la disposition de la hiérarchie du système de fichiers des _unix-like_, la FHS (Filesystem Hierarchy Standard). Pour fonctionner correctement, NixOS a besoin de faire beaucoup d'entorses à ladite FHS, entre autres : - il n'y a pas de `/usr`, et `/bin` ne contient qu'un élément - `/etc` n'est pratiquement composé que de liens symboliques. On peut expliquer ce choix par le fait que `nix` résout de manière correcte le problème que la FHS tente de contourner : chaque composant logiciel doit pouvoir trouver où les autres composants ont mis leurs fichiers. La FHS résout ce problème de manière _implicite_ avec des conventions (l'exécutable de `wmcoincoin` de référence sera dans `/usr/bin` ou une de ses variantes), tandis que `nix` le résout de manière explicite (on construit `wmblinkingcoincoin` avec en paramètre la référence de la version en usage de `wmcoincoin`). # Nixops Un système `nixos` étant entièrement défini à partir de son fichier `/etc/nixos/configuration.nix`, on peut décrire simplement le déploiement d'un parc de machines : telle machine devra avoir la configuration décrite par tel fichier `configuration.nix`. C'est sur ce principe que repose l'outil de déploiement réseau et de **distribution sur nuage _nixops_**. Le 30 avril dernier, [la version 1.2 de nixops est sortie](http://nixos.org/nixos/manual/#sec-release-14.04). Le rédacteur de la dépêche doit avouer sa méconnaissance de nixops, au-delà de son principe alléchant. Le [manuel](http://nixos.org/nixops/manual) et l'[exemple d'utilisation pour déployer une application node](http://zef.me/5981/deploying-a-simple-node-js-application-with-nixops) permettent de se faire une idée de la chose. # Nouveautés des dernières versions de l'écosystème nixos ## Nix 1.7 La version 1.7, sortie le 11 avril 2014 apporte [son lot de nouveautés](http://releases.nixos.org/nix/nix-1.7/manual/#ssec-relnotes-1.7) par rapport à la 1.6 (septembre 2013): - `nix-build --check` permet de construire à nouveau une dérivation existante et de vérifier si le résultat est le même. On peut ainsi faire la chasse aux sources de non-déterminisme dans le processus de construction (date de la compilation qui se retrouve dans l'exécutable ou autres) ; - `nix-shell -p` permet de lancer un environnement contenant (uniquement) une liste de paquets de nixpkgs ; - `nix-shell` utilise `shell.nix` comme expression par défaut ; en revanche, `nix-build` utilise toujours `default.nix`, ce qui permet d'avoir plus facilement une expression pour construire un projet, et une autre pour travailler dans son environnement de développement ; - `nix-env -q --json` donne une représentation JSON des paquets installés ou disponibles ; - le ramasse-miette du _store_ a été amélioré: on peut lui demander de libérer une quantité donnée d'espace, ou de préserver les paquets les plus récents, fussent-ils inutilisés ; - cette version introduit une gestion expérimentale des dépôts binaires crypto-signés. ## nixpkgs 14.04 De même, nixpkgs 14.04 se renouvelle, [avec notamment](https://github.com/NixOS/nixpkgs/issues/2112) : - gcc 4.9 - xorg-server 1.14 - mesa 10.1 - gtk 3.12 - kde 4.12 - gnome 3.10 (expérimental), il n'y avait pas de gnome du tout dans nixpkgs 13.10 - par défaut, nixpkgs est maintenant une collection de logiciels _libres_ : il faut passer la variable `allowUnfree` à `true` pour installer les dérivations de logiciels non-libres. ## NixOS 14.04 La mise à jour vers NixOS 14.04 se fait tout simplement en pointant le _channel_ système vers `http://nixos.org/channels/nixos-14.04`, puis en lançant `nixos-rebuild switch`. En plus des nouveautés héritées de nixpkg, les parties propres à NixOS ont changé : - par défaut, la gestion des comptes-utilisateurs peut se faire depuis `configuration.nix` plutôt que par `useradd` et `userdel` (de même pour les groupes) ; - l'installeur sait se débrouiller sur les machines UEFI ; - il est possible de créer des [_containers_ dans NixOS](http://hydra.nixos.org/build/10697542/download/2/nixos/manual.html#ch-containers), sortes de machines virtuelles légères pour les besoins ponctuels en virtualisation ; - par défaut, un pare-feu est mis en place à l'installation, ~~comme sous StarOffice~~ ; - le reste des changements est visible dans [la section idoine du manuel](http://hydra.nixos.org/build/10697542/download/2/nixos/manual.html#sec-release-14.04). # Guix, le nix de GNU [Ludovic Courtès](http://www.fdn.fr/~lcourtes), un hacker GNU particulièrement impliqué dans Guile a créé le premier dérivatif de NixOS, [Guix](http://www.gnu.org/software/guix/). De nix, il a gardé les couches basses, c'est-à-dire le store et le démon nix-daemon. En revanche, la définition des paquets et de la configuration du système se fait en [Guile](http://www.gnu.org/software/guile/), le dialecte Lisp de GNU. Du point de vue du contenu, nixpkgs est assez permissif avec les logiciels privateurs : ils sont présents dans nixpkgs et étaient installables par défaut jusque récemment. Guix, en tant que système GNU, est rigoureusement fidèle aux principes de la FSF ; il ne contient donc que des logiciels libres. Le slogan du projet est « Guix, the GNU system » (Guix, le système GNU), il s'agit donc d'une proposition pour réaliser une distribution du système GNU. À ce titre, il donne une place privilégiée, non seulement à Guile, mais aussi à d'autres briques logicielles GNU, comme [dmd](http://www.gnu.org/software/dmd/), un système d'init scriptable lui aussi en Guile. En revanche, il utilise pour le moment un noyau Linux et non Hurd. L'avantage recherché par Guix, c'est de se passer du langage nix, jugé ad-hoc, au profit de Guile (un langage lisp). Cela évite d'avoir à apprendre un nouveau langage pour écrire des dérivations (spécifications de paquets) et permet d'utiliser toutes les bibliothèques Guile dans la définition des dérivations. Cette démarche est expliquée dans le [papier de Ludovic Courtès présentant Guix](http://arxiv.org/abs/1305.4584). Les nouveautés de la version 0.6, sortie le 9 avril ont donné lieu à un [journal sur linuxfr](http://linuxfr.org/users/enclair/journaux/sortie-de-gnu-guix-0-6). Les principaux changements sont indiqués dans [l'annonce de cette version](http://lists.gnu.org/archive/html/guix-devel/2014-04/msg00160.html), ils concernent à la fois l'outil guix de gestion des paquets et le contenu de la collection de paquets. Cette version 0.6 ne permet toujours que l'exécution dans une machine virtuelle. Ludovic Courtès a indiqué le chemin restant à parcourir jusqu'à Guix 1.0 [dans un message sur la liste de guix](https://lists.gnu.org/archive/html/guix-devel/2013-12/msg00120.html). # Copylefts Les captures d'écrans et la figure explicative des liens enchaînés sont faites par Eelco Delstra, sous licence CC-By 4.0. La section « anatomie d'une dérivation » reprend la dérivation `pkgs/applications/science/biology/emboss`, qui est sous [licence MIT](https://github.com/NixOS/nixpkgs/blob/master/COPYING).

AltStyle によって変換されたページ (->オリジナル) /