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
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.
Sommaire
- Pourquoi utiliser Nix et NixOS ?
- Utilisation de nix et installation sur une distribution classique
- Fonctionnement de nix
- NixOS et ses particularités techniques
- Nixops
- Nouveautés des dernières versions de l'écosystème nixos
- Guix, le nix de GNU
- Copylefts
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 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 utilisables sans le mot de passe root. Cliquer sur un tel lien, par exemple celui pour quantumminigolf, permet d'installer un paquet et toutes ses dépendances.
Une autre distribution Linux, Pardus, une distribution turque, a utilisé à un moment un gestionnaire de paquets un peu comparable avec nix, Pisi. 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, 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 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 desudo
… -
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 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, etnix-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, 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 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. 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 ajouternixbld1, nixbld2
et seulement eux ; - donner au groupe
nixbld
les droits en écriture sur/nix/store
:
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. 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 et dans nixpkgs 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 perdu dans les bugs et défauts de conception de ces outils).
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:
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 :
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.
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 :
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.
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 :
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 :
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 :
let
nixpkgs = (import <nixpkgs> {})
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 :
$ sudo nix-channel --update
soit l'équivalent de :
$ 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 :
$ sudo nixos-rebuild switch
ce qui correspond (superficiellement) à :
$ 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
$ 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) :
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 :
$ 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
$ 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 :
i18n = {
consoleFont = "lat9w-16";
consoleKeyMap = "fr";
defaultLocale = "fr_FR.UTF-8";
};
ou celle pour SLiM, un utilitaire de login graphique :
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 :
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
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. Le rédacteur de la dépêche doit avouer sa méconnaissance de nixops, au-delà de son principe alléchant. Le manuel et l'exemple d'utilisation pour déployer une application node 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 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
utiliseshell.nix
comme expression par défaut ; en revanche,nix-build
utilise toujoursdefault.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 :
- 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 paruseradd
etuserdel
(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, 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.
Guix, le nix de GNU
Ludovic Courtès, un hacker GNU particulièrement impliqué dans Guile a créé le premier dérivatif de NixOS, 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, 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, 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.
Les nouveautés de la version 0.6, sortie le 9 avril ont donné lieu à un journal sur linuxfr. Les principaux changements sont indiqués dans l'annonce de cette version, 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.
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.
Aller plus loin
- Le projet Nix (473 clics)
- Le gestionnaire de paquets Nix (138 clics)
- La distribution Nixos (294 clics)
- Présentation de nix/nixos au fosdem 2014 (74 clics)
- La thèse séminale d'Eelco Dolstra (80 clics)
- Le canal irc de nix / nixos (30 clics)
- La liste de diffusion de nix / nixos (36 clics)
- Des webservices déclaratifs avec NixOS (présentation par Joachim Schiele, partie théorique) (65 clics)
- Une présentation général et démonstration de NixOS (partie pratique de la présentation par J Shiele) (78 clics)
- Distrowatch reviews: Deploying Software Sensibly with NixOS 13.10 (99 clics)
# Configurations utilisateur
Posté par enclair . Évalué à 10.
On peut installer plusieurs versions d'un logiciel en parallèle, ou revenir en arrière, cool.
Comment ça se passe pour les fichiers de configuration qui sont dans $HOME, comme ~/.mozilla ?
Sont-ils aussi versionnés ? Comment les conflits sont-ils gérés ? (par exemple pour kmail la configuration est compatible lorsqu'on met à jour, mais pas forcément lorqu'on revient en arrière).
[^] # Re: Configurations utilisateur
Posté par galbolle . Évalué à 9.
Il y a trois niveaux de réponse:
$HOME
, et nix en ignore l'existence. Du coup, l'installation de plusieurs versions en parallèle ou les retours en arrière peuvent être périlleux. En pratique, ça ne marche pas si mal;[^] # Re: Configurations utilisateur
Posté par Maclag . Évalué à 9.
Si je peux me permettre, une partie de la réponse tient en amont dans le développement des logiciels eux-mêmes. La réponse ne peut pas être dans le gestionnaire de paquets.
Pourquoi 2 versions de KMail ne peuvent pas utiliser le même répertoire de configuration? (et ainsi de suite pour tous les autres). Pour la plupart des logiciels, ce n'est simplement pas prévu!
On ne peut pas demander à un gestionnaire de paquet de faire ce boulot-là. Et à l'heure du "cloud", si on envisage d'avoir la config dans le nuage et de pouvoir y accéder depuis n'importe quel poste connecté, il faut que la configuration soit lisible par n'importe quelle version de l'appli (on trouve déjà ça ailleurs, avec des messages genre "la config vient d'une version supérieure à celle que vous utilisez, il se peut que certaines fonctionnalités ne soient pas présentes etc.").
Il ne faudra pas longtemps avant que ça devienne une fonctionnalité "clé" pour les clients "lourds", parce que les clients web ne souffrent pas de ce problème.
[^] # Re: Configurations utilisateur
Posté par claudex . Évalué à 4.
Pour la configuration, ça pose un problème. Par exemple, le choix d'un backend, dans la version X, la configuration permet sqlite et pgsql. Lors du passage à la version Y, la possibilité d'utiliser mongodb apparaît. Tu décides d'utiliser la version Y avec mongodb et puis tu reviens en arrière à la version X. Tu as fait le bourrin en changeant de version et tu te retrouves avec un fichier de config qui ressemble à
Comment le logiciel peut savoir qu'il doit utiliser pgsql et se connecter à 198.51.100.24, sans compter que les données ne seront pas migrées ?
Pour les données, c'est aussi un problème. Par exemple avec la version X, on stocke les données en XML, avec la version Y, on décide d'utiliser un format binaire, comment la version X pourrait lire les données en binaire ?
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Configurations utilisateur
Posté par Maclag . Évalué à 6.
Là tu parles de changements majeurs, déjà ça n'arrive pas tous les jours.
Ensuite, pour l'exemple des bases de données, supposons que l'option "configuration partagée" ou "config cloud" ou appellation similaire, je dirais que la question ne se poserait pas:
-soit ta première utilisation de l'outil est la version Y qui utilise MongoDB et là effectivement, tu es coincé jusqu'à ce que ça migre partout ; mais à la configuration, tu peux afficher un avertissement
-soit ta première utilisation est sur la version X, et quand tu lances la version Y pour la première fois, et que le logiciel te le demande, tu ne cliques pas sur "créer une base MongoDB", mais "utiliser une configuration existante"
La migration vers MongoDB devra se faire, sûrement sur demande de l'utilisateur, plus tard, quand l'utilisateur se sera lui-même assuré que toutes ses versions peuvent le faire. (Mais avouons-le: ce n'est pas une solution pour les utilisateurs lambda).
Ou alors (plus compliqué!), on peut imaginer que le logiciel maintienne un journal également en ligne de tous les clients qui y accèdent avec leurs versions. Passé un certain temps, un client peut proposer une migration sur la base "tous les clients que vous avez utilisés depuis xxx temps sont capables d'utiliser la nouvelle génération de stockage de données, voulez-vous effectuer la migration vers la nouvelle génération?"
Beaucoup plus simple: l'accès aux données est fait via un wrapper, et le client connecté n'a pas besoin de savoir quelle base de données est utilisée derrière, il ne voit qu'une API. Les clients sont capables d'utiliser une partie ou la totalité de l'API suivant leur version.
Évidemment, ça fait beaucoup de "yaka".
[^] # Re: Configurations utilisateur
Posté par claudex . Évalué à 4.
On est bien d'accord.
Ça ne fait que déporter le problème, tu peux très bien avoir un changement nécessaire d'API pour les perfs, les fonctionnalités… Et le wrapper, il faut le mettre à jour si tu héberge toi-même le service.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
# Installateurs universels ?
Posté par coid . Évalué à 3.
Ici, on peine à gérer Gnome. Dans la dépêche précédente on appelle à l’aide pour gérer KDE. Il fut un temps où s’occuper d’OpenOffice.org était aussi une tâche qui requerrait bien des efforts (j’ignore si c’est encore le cas avec LibreOffice).
Qu’est-ce qui fait obstacle à ce qu’il y ait enfin des installateurs universels sur Linux ? Pourquoi faut-il que chaque distribution ait à gérer ses paquets ? La gestion de ces paquets occupe un temps considérable pour les distributions, semble-t-il. Pourquoi c’est si complexe ? Les applications portables, c’est pas bien ?
[^] # Re: Installateurs universels ?
Posté par galbolle . Évalué à 5.
Pour la difficulté à avoir Gnome sous NixOS, c'est lié à la fois à Gnome et à NixOS. Gnome met plein de choses dans gconf, qui devient de fait un « système de fichiers » auxiliaire. Comme nix insiste pour fonctionner en séparant l'empreinte des différents paquets/versions sur le système de fichier, il faut réimplémenter pas mal de choses pour gnome.
À mon avis, les fonctionnalités qu'apporte nix par rapport aux gestionnaires de paquets des versions précédentes (notamment le fait de pouvoir installer des paquets sans accès root) en font un candidat pour implémenter ces «installateurs universels». Mais il reste beaucoup à faire pour ça, que ce soit du point de vue sécurité (dans le store, c'est «tout ou rien» pour l'instant) ou pour être accepté dans la communauté.
[^] # Re: Installateurs universels ?
Posté par claudex . Évalué à 5.
Les distributions n'ont pas les mêmes versions de logiciels/bibliothèques, ça entraîne des bugs particuliers sur certaines distribution qui demande du temps à corriger. Les politiques des distributions ne sont pas non plus toujours les mêmes que celles des logiciels sources. Par exemple, bien avant que Qt se sépare en plusieurs modules, c'était déjà empaqueter de cette manière sous Debian, ça demande du boulot au mainteneurs pour séparer correctement et ça génère aussi des nouveaux bugs, mais ça apporte plus de fonctionnalités. Il y a aussi la fin du support par l'upstream alors que la version est toujours prise en charge par la distribution.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Installateurs universels ?
Posté par Maclag . Évalué à 5.
Parce qu'il y a autant de systèmes de paquets que de groupes totalement convaincus que leur système de paquet est le meilleur et que si on en choisit un, ce devrait forcément être le leur!
Quant à l'installateur universel, 2 approches possibles:
-une standardisation à la LSB (on a vu ce que ça a donné par le passé: d'abord pas grand chose puis plus rien du tout)
-des paquets "autonomes", c'est-à-dire pré-compilés en statique pour éviter les soucis avec les différentes versions de chaque bibliothèque dans les différentes distros. Et là on perd les bienfaits des gestionnaires de paquets et de dépendance (parce qu'on décide de les ignorer).
Après, on peut imaginer une nouvelle formule, genre une standardisation des instructions de compilation, et une commande "commune" dans l'appel mais spécifique à chaque distro. Comme au lieu d'avoir un "setup.exe" qui installe un logiciel, tu aurais un "super-make.sh" qui compile, fabrique un paquet spécifique pour ta distro et l'installe.
Mais c'est plus facile à décrire en quelques lignes qu'à faire (et bonjour la batterie de tests pour les développeurs!!).
[^] # Re: Installateurs universels ?
Posté par galbolle . Évalué à 3.
Je vais développer les raisons qui me font penser, au-delà de « chacun voit midi à sa porte », que nix est une bonne base pour de tels paquets universels.
Nix donne de tels paquets « autonomes », sous forme de one-click-installs. Ces paquets ont des liens dynamiques, mais vers des bibliothèques dont le chemin est défini statiquement. Tu as ainsi les assurances des liens statiques, mais avec les avantages (notamment mémoire) des liens dynamiques. Nix garde également les traces des dépendances, et il pourrait avertir si on installe une mise à jour (de sécurité par exemple) d'une bibliothèque dont dépend un tel paquet.
Nix apporte là aussi une réponse avec hydra. L'approche déclarative de nixos permet de décrire des tests unitaires qui parlent de « la machines obtenue en installant tels paquets, configurés de la façon suivante ». Ça fait certes une batterie de tests impressionante, mais on a un langage propre pour la décrire et une architecture pour la faire tourner.
[^] # Re: Installateurs universels ?
Posté par doom_Oo7 . Évalué à 0.
Sous CMake avec CPack et
c'est simple à faire.
Sinon sous Debian il y a
qui appelle make install, crée un .deb avec le résultat et l'installe.
Personnellement, ce que j'aimerais bien c'est un gestionnaire de paquet à la ports qui permette explicitement (avec une petite interface graphique?) de lister les fonctionnalités qu'on veut dans un log (parmi celles configurables), de chercher uniquement les dépendances pour ces fonctionnalités et de le compiler comme ça.
[^] # Re: Installateurs universels ?
Posté par claudex . Évalué à 5.
emerge ?
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
# concept "fabuleux"
Posté par demsking . Évalué à 1.
Je suis nouveau ici et je suis accueilli avec un bel article !
Je ne connaissais pas cette solution.
Belle description de Nix/NixOS… je trouve le concept "fabuleux". une vrai fonctionalité des "Restauration système" que j'ai toujours cherché dans l'univers GNU/Linux. J'en avais encore besoin il y a 2 semaines… j'ai du reinstallé mon système car ne possédant pas toutes les connaissances à la geek pour restaurer mon système.
Juste pour savoir… puis je migrer de Kubuntu 14.04 vers NixOS 14.04 sans soucis ?
[^] # Re: concept "fabuleux"
Posté par Maclag . Évalué à 5.
Je ne fais pas partie du projet et pour être franc, je n'ai jamais essayé NixOS. Mais ça veut aussi dire que je ne suis pas impliqué émotionnellement.
Mon conseil serait de ne pas migrer, parce que tu débutes, et parce que NixOS est un projet encore très jeune comparé aux distributions dites grand public. Un projet très jeune avec une base utilisateur réduite, ça veut dire qu'il faut s'attendre à rencontrer beaucoup de problèmes de jeunesse, simplement parce que plus la base utilisateur est réduite, plus il y a de chances que ton propre cas d'utilisation soit un cas particulier.
En plus, un système exotique signifie que peu de personnes seront disponibles pour t'aider.
NixOS fait également des choix très radicaux sur certains points, ce qui veut dire qu'il va falloir un peu de bagage pour adapter les infos que tu trouverais en ligne au cas particulier NixOS.
Kubuntu dispose d'une grosse base utilisateur et d'une grosse communauté. Dans le petit monde Linux, c'est très important parce que tu vas en avoir besoin pour trouver des solutions à tes problèmes.
[^] # Re: concept "fabuleux"
Posté par Chaddaï Fouché . Évalué à 4.
Ce que dit maclag est vrai mais en même temps, l'un des avantages de NixOS c'est qu'une fois installée, tu es assez tranquille : même s'il y a des changements qui cassent ta distribution, tu peux toujours revenir en arrière (même si elle ne démarre plus comme expliqué dans l'article). NixOS est très robuste de ce point de vue, bien plus que des distributions plus matures.
Je dirais que le principal écueil que tu risques de rencontrer c'est le nombre de paquets, si tu as des besoins bien particuliers. Ce n'est pas comme si nixpkgs était vide, la plupart des gros paquets y sont (bureautique, édition, internet, graphisme, etc) mais si tu veux un logiciel à l'écart des sentiers battus… il faudra peut-être que tu fasses un paquet pour l'ajouter à nixpkgs, ce n'est pas trop difficile (c'est même très simple pour un logiciel bien conçu comme le montre l'exemple dans l'article, mais si le modèle de déploiement est très non-standard, ça peut devenir plus dur).
# aur2nix
Posté par leovilok . Évalué à 2.
Il y a 48467 paquets dans AUR (Arch User Repository), dont à peu près la moitié sont maintenus/à-jour et la majorité des autres fonctionnent, la plus part contiennent des recettes de compilation : n'y aurait-il pas moyen de les traduire automatiquement pour nix ? (C'est sûrement pareil pour Gentoo mais je connais pas)
[^] # Re: aur2nix
Posté par galbolle . Évalué à 2.
C'est effectivement quelque chose de naturel à tenter. Après, il faut pouvoir assurer le suivi, et je pense que personne ne veut se retrouver responsable de dizaines de milliers de paquets hétérogènes.
[^] # Re: aur2nix
Posté par galbolle . Évalué à 3.
Pour compléter, les paquets faits à partir de cabal, npm ou autres gestionnaires de paquets propres à un langage ont des processus de constructions très homogènes, ce qui fait que l'automatisation marche très bien. Pour AUR, les paquets sont beaucoup plus hétérogènes, et si la partie facile qui prend <5min / package pourrait s'automatiser ainsi, au total on ne gagnerait pas grand-chose, car il faudra repasser bien trop souvent derrière la moulinette.
# Bourde?
Posté par MCMic (site web personnel) . Évalué à 4.
Dans les exemples d’installation et de switch, je pige pas cette ligne:
C’est pas «/nix/var/nix/profiles/per-user/suzanne» comme sur les autres lignes? C’est qui ce user2, on le voit propriétaire des dossiers listés avec ls.
Et pourquoi il faut passer autant d’option pour changer de contexte et s’occuper d’où ils sont stockés, je m’attendais plus à un «nix-bidule --list-profile» et «nix-bidule --switch-profile monprofil»?
[^] # Re: Bourde?
Posté par galbolle . Évalué à 2.
Effectivement, le «user2» c'est une bourde, ça devrait être suzanne partout. J'ai réécrit ces lignes au dernier moment pour que ce soit plus clair, et j'ai oublié des occurences. Si un modérateur passe par là, s/user2/suzanne/g.
Pour les outils, ta suggestion est effectivement raisonnable, je m'attendais à ce que ça marche comme ça aussi au début. Comme (semi-bonnes) raisons, je vois:
[^] # Re: Bourde?
Posté par Benoît Sibaud (site web personnel) . Évalué à 3.
Corrigé, merci.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.